<p>Joshua Colp has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/16312">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">chan_phone: Remove deprecated module.<br><br>ASTERISK-29594<br><br>Change-Id: I79a9961cb5062fadbccb0ea93f087bdd32685316<br>---<br>M build_tools/menuselect-deps.in<br>D channels/chan_phone.c<br>M configure<br>M configure.ac<br>A doc/UPGRADE-staging/chan_phone_removal.txt<br>M menuselect/configure<br>6 files changed, 41 insertions(+), 1,553 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/12/16312/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/build_tools/menuselect-deps.in b/build_tools/menuselect-deps.in</span><br><span>index 161c67b..25f3049 100644</span><br><span>--- a/build_tools/menuselect-deps.in</span><br><span>+++ b/build_tools/menuselect-deps.in</span><br><span>@@ -24,7 +24,6 @@</span><br><span> IMAP_TK=@PBX_IMAP_TK@</span><br><span> IODBC=@PBX_IODBC@</span><br><span> ISDNNET=@PBX_ISDNNET@</span><br><span style="color: hsl(0, 100%, 40%);">-IXJUSER=@PBX_IXJUSER@</span><br><span> JACK=@PBX_JACK@</span><br><span> JANSSON=@PBX_JANSSON@</span><br><span> URIPARSER=@PBX_URIPARSER@</span><br><span>diff --git a/channels/chan_phone.c b/channels/chan_phone.c</span><br><span>deleted file mode 100644</span><br><span>index 66c911b..0000000</span><br><span>--- a/channels/chan_phone.c</span><br><span>+++ /dev/null</span><br><span>@@ -1,1519 +0,0 @@</span><br><span style="color: hsl(0, 100%, 40%);">-/*</span><br><span style="color: hsl(0, 100%, 40%);">- * Asterisk -- An open source telephony toolkit.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * Copyright (C) 1999 - 2005, Digium, Inc.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * Mark Spencer <markster@digium.com></span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * See http://www.asterisk.org for more information about</span><br><span style="color: hsl(0, 100%, 40%);">- * the Asterisk project. Please do not directly contact</span><br><span style="color: hsl(0, 100%, 40%);">- * any of the maintainers of this project for assistance;</span><br><span style="color: hsl(0, 100%, 40%);">- * the project provides a web site, mailing lists and IRC</span><br><span style="color: hsl(0, 100%, 40%);">- * channels for your use.</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * This program is free software, distributed under the terms of</span><br><span style="color: hsl(0, 100%, 40%);">- * the GNU General Public License Version 2. See the LICENSE file</span><br><span style="color: hsl(0, 100%, 40%);">- * at the top of the source tree.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*! \file</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * \brief Generic Linux Telephony Interface driver</span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * \author Mark Spencer <markster@digium.com></span><br><span style="color: hsl(0, 100%, 40%);">- *</span><br><span style="color: hsl(0, 100%, 40%);">- * \ingroup channel_drivers</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*! \li \ref chan_phone.c uses the configuration file \ref phone.conf</span><br><span style="color: hsl(0, 100%, 40%);">- * \addtogroup configuration_file</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*! \page phone.conf phone.conf</span><br><span style="color: hsl(0, 100%, 40%);">- * \verbinclude phone.conf.sample</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/*** MODULEINFO</span><br><span style="color: hsl(0, 100%, 40%);">- <depend>ixjuser</depend></span><br><span style="color: hsl(0, 100%, 40%);">- <support_level>deprecated</support_level></span><br><span style="color: hsl(0, 100%, 40%);">- <deprecated_in>16</deprecated_in></span><br><span style="color: hsl(0, 100%, 40%);">- <removed_in>19</removed_in></span><br><span style="color: hsl(0, 100%, 40%);">- ***/</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk.h"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include <ctype.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <sys/socket.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <sys/time.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <arpa/inet.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <fcntl.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <sys/ioctl.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <signal.h></span><br><span style="color: hsl(0, 100%, 40%);">-#ifdef HAVE_LINUX_COMPILER_H</span><br><span style="color: hsl(0, 100%, 40%);">-#include <linux/compiler.h></span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-#include <linux/telephony.h></span><br><span style="color: hsl(0, 100%, 40%);">-/* Still use some IXJ specific stuff */</span><br><span style="color: hsl(0, 100%, 40%);">-#include <linux/version.h></span><br><span style="color: hsl(0, 100%, 40%);">-#include <linux/ixjuser.h></span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/lock.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/channel.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/config.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/module.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/pbx.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/utils.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/callerid.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/causes.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/stringfields.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/musiconhold.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/format_cache.h"</span><br><span style="color: hsl(0, 100%, 40%);">-#include "asterisk/format_compatibility.h"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#include "chan_phone.h"</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#ifdef QTI_PHONEJACK_TJ_PCI /* check for the newer quicknet driver v.3.1.0 which has this symbol */</span><br><span style="color: hsl(0, 100%, 40%);">-#define QNDRV_VER 310</span><br><span style="color: hsl(0, 100%, 40%);">-#else</span><br><span style="color: hsl(0, 100%, 40%);">-#define QNDRV_VER 100</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#if QNDRV_VER > 100</span><br><span style="color: hsl(0, 100%, 40%);">-#ifdef __linux__</span><br><span style="color: hsl(0, 100%, 40%);">-#define IXJ_PHONE_RING_START(x) ioctl(p->fd, PHONE_RING_START, &x);</span><br><span style="color: hsl(0, 100%, 40%);">-#else /* FreeBSD and others */</span><br><span style="color: hsl(0, 100%, 40%);">-#define IXJ_PHONE_RING_START(x) ioctl(p->fd, PHONE_RING_START, x);</span><br><span style="color: hsl(0, 100%, 40%);">-#endif /* __linux__ */</span><br><span style="color: hsl(0, 100%, 40%);">-#else /* older driver */</span><br><span style="color: hsl(0, 100%, 40%);">-#define IXJ_PHONE_RING_START(x) ioctl(p->fd, PHONE_RING_START, &x);</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define DEFAULT_CALLER_ID "Unknown"</span><br><span style="color: hsl(0, 100%, 40%);">-#define PHONE_MAX_BUF 480</span><br><span style="color: hsl(0, 100%, 40%);">-#define DEFAULT_GAIN 0x100</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static const char tdesc[] = "Standard Linux Telephony API Driver";</span><br><span style="color: hsl(0, 100%, 40%);">-static const char config[] = "phone.conf";</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Default context for dialtone mode */</span><br><span style="color: hsl(0, 100%, 40%);">-static char context[AST_MAX_EXTENSION] = "default";</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Default language */</span><br><span style="color: hsl(0, 100%, 40%);">-static char language[MAX_LANGUAGE] = "";</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int echocancel = AEC_OFF;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int silencesupression = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ast_format_cap *prefcap;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Protect the interface list (of phone_pvt's) */</span><br><span style="color: hsl(0, 100%, 40%);">-AST_MUTEX_DEFINE_STATIC(iflock);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Protect the monitoring thread, so only one process can kill or start it, and not</span><br><span style="color: hsl(0, 100%, 40%);">- when it's doing something critical. */</span><br><span style="color: hsl(0, 100%, 40%);">-AST_MUTEX_DEFINE_STATIC(monlock);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Boolean value whether the monitoring thread shall continue. */</span><br><span style="color: hsl(0, 100%, 40%);">-static unsigned int monitor;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* This is the thread for the monitor which checks for input on the channels</span><br><span style="color: hsl(0, 100%, 40%);">- which are not currently in use. */</span><br><span style="color: hsl(0, 100%, 40%);">-static pthread_t monitor_thread = AST_PTHREADT_NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int restart_monitor(void);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* The private structures of the Phone Jack channels are linked for</span><br><span style="color: hsl(0, 100%, 40%);">- selecting outgoing channels */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#define MODE_DIALTONE 1</span><br><span style="color: hsl(0, 100%, 40%);">-#define MODE_IMMEDIATE 2</span><br><span style="color: hsl(0, 100%, 40%);">-#define MODE_FXO 3</span><br><span style="color: hsl(0, 100%, 40%);">-#define MODE_FXS 4</span><br><span style="color: hsl(0, 100%, 40%);">-#define MODE_SIGMA 5</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct phone_pvt {</span><br><span style="color: hsl(0, 100%, 40%);">- int fd; /* Raw file descriptor for this device */</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_channel *owner; /* Channel we belong to, possibly NULL */</span><br><span style="color: hsl(0, 100%, 40%);">- int mode; /* Is this in the */</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_format *lastformat; /* Last output format */</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_format *lastinput; /* Last input format */</span><br><span style="color: hsl(0, 100%, 40%);">- int ministate; /* Miniature state, for dialtone mode */</span><br><span style="color: hsl(0, 100%, 40%);">- char dev[256]; /* Device name */</span><br><span style="color: hsl(0, 100%, 40%);">- struct phone_pvt *next; /* Next channel in list */</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_frame fr; /* Frame */</span><br><span style="color: hsl(0, 100%, 40%);">- char offset[AST_FRIENDLY_OFFSET];</span><br><span style="color: hsl(0, 100%, 40%);">- char buf[PHONE_MAX_BUF]; /* Static buffer for reading frames */</span><br><span style="color: hsl(0, 100%, 40%);">- int obuflen;</span><br><span style="color: hsl(0, 100%, 40%);">- int dialtone;</span><br><span style="color: hsl(0, 100%, 40%);">- int txgain, rxgain; /* gain control for playing, recording */</span><br><span style="color: hsl(0, 100%, 40%);">- /* 0x100 - 1.0, 0x200 - 2.0, 0x80 - 0.5 */</span><br><span style="color: hsl(0, 100%, 40%);">- int cpt; /* Call Progress Tone playing? */</span><br><span style="color: hsl(0, 100%, 40%);">- int silencesupression;</span><br><span style="color: hsl(0, 100%, 40%);">- char context[AST_MAX_EXTENSION];</span><br><span style="color: hsl(0, 100%, 40%);">- char obuf[PHONE_MAX_BUF * 2];</span><br><span style="color: hsl(0, 100%, 40%);">- char ext[AST_MAX_EXTENSION];</span><br><span style="color: hsl(0, 100%, 40%);">- char language[MAX_LANGUAGE];</span><br><span style="color: hsl(0, 100%, 40%);">- char cid_num[AST_MAX_EXTENSION];</span><br><span style="color: hsl(0, 100%, 40%);">- char cid_name[AST_MAX_EXTENSION];</span><br><span style="color: hsl(0, 100%, 40%);">-} *iflist = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static char cid_num[AST_MAX_EXTENSION];</span><br><span style="color: hsl(0, 100%, 40%);">-static char cid_name[AST_MAX_EXTENSION];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ast_channel *phone_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause);</span><br><span style="color: hsl(0, 100%, 40%);">-static int phone_digit_begin(struct ast_channel *ast, char digit);</span><br><span style="color: hsl(0, 100%, 40%);">-static int phone_digit_end(struct ast_channel *ast, char digit, unsigned int duration);</span><br><span style="color: hsl(0, 100%, 40%);">-static int phone_call(struct ast_channel *ast, const char *dest, int timeout);</span><br><span style="color: hsl(0, 100%, 40%);">-static int phone_hangup(struct ast_channel *ast);</span><br><span style="color: hsl(0, 100%, 40%);">-static int phone_answer(struct ast_channel *ast);</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ast_frame *phone_read(struct ast_channel *ast);</span><br><span style="color: hsl(0, 100%, 40%);">-static int phone_write(struct ast_channel *ast, struct ast_frame *frame);</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ast_frame *phone_exception(struct ast_channel *ast);</span><br><span style="color: hsl(0, 100%, 40%);">-static int phone_send_text(struct ast_channel *ast, const char *text);</span><br><span style="color: hsl(0, 100%, 40%);">-static int phone_fixup(struct ast_channel *old, struct ast_channel *new);</span><br><span style="color: hsl(0, 100%, 40%);">-static int phone_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ast_channel_tech phone_tech = {</span><br><span style="color: hsl(0, 100%, 40%);">- .type = "Phone",</span><br><span style="color: hsl(0, 100%, 40%);">- .description = tdesc,</span><br><span style="color: hsl(0, 100%, 40%);">- .requester = phone_request,</span><br><span style="color: hsl(0, 100%, 40%);">- .send_digit_begin = phone_digit_begin,</span><br><span style="color: hsl(0, 100%, 40%);">- .send_digit_end = phone_digit_end,</span><br><span style="color: hsl(0, 100%, 40%);">- .call = phone_call,</span><br><span style="color: hsl(0, 100%, 40%);">- .hangup = phone_hangup,</span><br><span style="color: hsl(0, 100%, 40%);">- .answer = phone_answer,</span><br><span style="color: hsl(0, 100%, 40%);">- .read = phone_read,</span><br><span style="color: hsl(0, 100%, 40%);">- .write = phone_write,</span><br><span style="color: hsl(0, 100%, 40%);">- .exception = phone_exception,</span><br><span style="color: hsl(0, 100%, 40%);">- .indicate = phone_indicate,</span><br><span style="color: hsl(0, 100%, 40%);">- .fixup = phone_fixup</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ast_channel_tech phone_tech_fxs = {</span><br><span style="color: hsl(0, 100%, 40%);">- .type = "Phone",</span><br><span style="color: hsl(0, 100%, 40%);">- .description = tdesc,</span><br><span style="color: hsl(0, 100%, 40%);">- .requester = phone_request,</span><br><span style="color: hsl(0, 100%, 40%);">- .send_digit_begin = phone_digit_begin,</span><br><span style="color: hsl(0, 100%, 40%);">- .send_digit_end = phone_digit_end,</span><br><span style="color: hsl(0, 100%, 40%);">- .call = phone_call,</span><br><span style="color: hsl(0, 100%, 40%);">- .hangup = phone_hangup,</span><br><span style="color: hsl(0, 100%, 40%);">- .answer = phone_answer,</span><br><span style="color: hsl(0, 100%, 40%);">- .read = phone_read,</span><br><span style="color: hsl(0, 100%, 40%);">- .write = phone_write,</span><br><span style="color: hsl(0, 100%, 40%);">- .exception = phone_exception,</span><br><span style="color: hsl(0, 100%, 40%);">- .write_video = phone_write,</span><br><span style="color: hsl(0, 100%, 40%);">- .send_text = phone_send_text,</span><br><span style="color: hsl(0, 100%, 40%);">- .indicate = phone_indicate,</span><br><span style="color: hsl(0, 100%, 40%);">- .fixup = phone_fixup</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ast_channel_tech *cur_tech;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int phone_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct phone_pvt *p = ast_channel_tech_pvt(chan);</span><br><span style="color: hsl(0, 100%, 40%);">- int res=-1;</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "Requested indication %d on channel %s\n", condition, ast_channel_name(chan));</span><br><span style="color: hsl(0, 100%, 40%);">- switch(condition) {</span><br><span style="color: hsl(0, 100%, 40%);">- case AST_CONTROL_FLASH:</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_ON_HOOK);</span><br><span style="color: hsl(0, 100%, 40%);">- usleep(320000);</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_OFF_HOOK);</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_cleanup(p->lastformat);</span><br><span style="color: hsl(0, 100%, 40%);">- p->lastformat = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- res = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- case AST_CONTROL_HOLD:</span><br><span style="color: hsl(0, 100%, 40%);">- ast_moh_start(chan, data, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- case AST_CONTROL_UNHOLD:</span><br><span style="color: hsl(0, 100%, 40%);">- ast_moh_stop(chan);</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- case AST_CONTROL_SRCUPDATE:</span><br><span style="color: hsl(0, 100%, 40%);">- res = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- case AST_CONTROL_PVT_CAUSE_CODE:</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- default:</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Condition %d is not supported on channel %s\n", condition, ast_channel_name(chan));</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- return res;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int phone_fixup(struct ast_channel *old, struct ast_channel *new)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct phone_pvt *pvt = ast_channel_tech_pvt(old);</span><br><span style="color: hsl(0, 100%, 40%);">- if (pvt && pvt->owner == old)</span><br><span style="color: hsl(0, 100%, 40%);">- pvt->owner = new;</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int phone_digit_begin(struct ast_channel *chan, char digit)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- /* XXX Modify this callback to let Asterisk support controlling the length of DTMF */</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int phone_digit_end(struct ast_channel *ast, char digit, unsigned int duration)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct phone_pvt *p;</span><br><span style="color: hsl(0, 100%, 40%);">- int outdigit;</span><br><span style="color: hsl(0, 100%, 40%);">- p = ast_channel_tech_pvt(ast);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "Dialed %c\n", digit);</span><br><span style="color: hsl(0, 100%, 40%);">- switch(digit) {</span><br><span style="color: hsl(0, 100%, 40%);">- case '0':</span><br><span style="color: hsl(0, 100%, 40%);">- case '1':</span><br><span style="color: hsl(0, 100%, 40%);">- case '2':</span><br><span style="color: hsl(0, 100%, 40%);">- case '3':</span><br><span style="color: hsl(0, 100%, 40%);">- case '4':</span><br><span style="color: hsl(0, 100%, 40%);">- case '5':</span><br><span style="color: hsl(0, 100%, 40%);">- case '6':</span><br><span style="color: hsl(0, 100%, 40%);">- case '7':</span><br><span style="color: hsl(0, 100%, 40%);">- case '8':</span><br><span style="color: hsl(0, 100%, 40%);">- case '9':</span><br><span style="color: hsl(0, 100%, 40%);">- outdigit = digit - '0';</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- case '*':</span><br><span style="color: hsl(0, 100%, 40%);">- outdigit = 11;</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- case '#':</span><br><span style="color: hsl(0, 100%, 40%);">- outdigit = 12;</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- case 'f': /*flash*/</span><br><span style="color: hsl(0, 100%, 40%);">- case 'F':</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_ON_HOOK);</span><br><span style="color: hsl(0, 100%, 40%);">- usleep(320000);</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_OFF_HOOK);</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_cleanup(p->lastformat);</span><br><span style="color: hsl(0, 100%, 40%);">- p->lastformat = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">- default:</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unknown digit '%c'\n", digit);</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "Dialed %d\n", outdigit);</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, PHONE_PLAY_TONE, outdigit);</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_cleanup(p->lastformat);</span><br><span style="color: hsl(0, 100%, 40%);">- p->lastformat = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int phone_call(struct ast_channel *ast, const char *dest, int timeout)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct phone_pvt *p;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- PHONE_CID cid;</span><br><span style="color: hsl(0, 100%, 40%);">- struct timeval UtcTime = ast_tvnow();</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_tm tm;</span><br><span style="color: hsl(0, 100%, 40%);">- int start;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ast_localtime(&UtcTime, &tm, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- memset(&cid, 0, sizeof(PHONE_CID));</span><br><span style="color: hsl(0, 100%, 40%);">- snprintf(cid.month, sizeof(cid.month), "%02d",(tm.tm_mon + 1));</span><br><span style="color: hsl(0, 100%, 40%);">- snprintf(cid.day, sizeof(cid.day), "%02d", tm.tm_mday);</span><br><span style="color: hsl(0, 100%, 40%);">- snprintf(cid.hour, sizeof(cid.hour), "%02d", tm.tm_hour);</span><br><span style="color: hsl(0, 100%, 40%);">- snprintf(cid.min, sizeof(cid.min), "%02d", tm.tm_min);</span><br><span style="color: hsl(0, 100%, 40%);">- /* the standard format of ast->callerid is: "name" <number>, but not always complete */</span><br><span style="color: hsl(0, 100%, 40%);">- if (!ast_channel_connected(ast)->id.name.valid</span><br><span style="color: hsl(0, 100%, 40%);">- || ast_strlen_zero(ast_channel_connected(ast)->id.name.str)) {</span><br><span style="color: hsl(0, 100%, 40%);">- strcpy(cid.name, DEFAULT_CALLER_ID);</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_copy_string(cid.name, ast_channel_connected(ast)->id.name.str, sizeof(cid.name));</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_channel_connected(ast)->id.number.valid && ast_channel_connected(ast)->id.number.str) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_copy_string(cid.number, ast_channel_connected(ast)->id.number.str, sizeof(cid.number));</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- p = ast_channel_tech_pvt(ast);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if ((ast_channel_state(ast) != AST_STATE_DOWN) && (ast_channel_state(ast) != AST_STATE_RESERVED)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "phone_call called on %s, neither down nor reserved\n", ast_channel_name(ast));</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "Ringing %s on %s (%d)\n", dest, ast_channel_name(ast), ast_channel_fd(ast, 0));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- start = IXJ_PHONE_RING_START(cid);</span><br><span style="color: hsl(0, 100%, 40%);">- if (start == -1)</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (p->mode == MODE_FXS) {</span><br><span style="color: hsl(0, 100%, 40%);">- const char *digit = strchr(dest, '/');</span><br><span style="color: hsl(0, 100%, 40%);">- if (digit)</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">- digit++;</span><br><span style="color: hsl(0, 100%, 40%);">- while (*digit)</span><br><span style="color: hsl(0, 100%, 40%);">- phone_digit_end(ast, *digit++, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ast_setstate(ast, AST_STATE_RINGING);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_queue_control(ast, AST_CONTROL_RINGING);</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int phone_hangup(struct ast_channel *ast)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct phone_pvt *p;</span><br><span style="color: hsl(0, 100%, 40%);">- p = ast_channel_tech_pvt(ast);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "phone_hangup(%s)\n", ast_channel_name(ast));</span><br><span style="color: hsl(0, 100%, 40%);">- if (!ast_channel_tech_pvt(ast)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Asked to hangup channel not connected\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- /* XXX Is there anything we can do to really hang up except stop recording? */</span><br><span style="color: hsl(0, 100%, 40%);">- ast_setstate(ast, AST_STATE_DOWN);</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_REC_STOP))</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Failed to stop recording\n");</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_PLAY_STOP))</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Failed to stop playing\n");</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_RING_STOP))</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Failed to stop ringing\n");</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_CPT_STOP))</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Failed to stop sounds\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* If it's an FXO, hang them up */</span><br><span style="color: hsl(0, 100%, 40%);">- if (p->mode == MODE_FXO) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_PSTN_SET_STATE, PSTN_ON_HOOK))</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "ioctl(PHONE_PSTN_SET_STATE) failed on %s (%s)\n",ast_channel_name(ast), strerror(errno));</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* If they're off hook, give a busy signal */</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_HOOKSTATE)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "Got hunghup, giving busy signal\n");</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, PHONE_BUSY);</span><br><span style="color: hsl(0, 100%, 40%);">- p->cpt = 1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_cleanup(p->lastformat);</span><br><span style="color: hsl(0, 100%, 40%);">- p->lastformat = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_cleanup(p->lastinput);</span><br><span style="color: hsl(0, 100%, 40%);">- p->lastinput = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- p->ministate = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- p->obuflen = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- p->dialtone = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- memset(p->ext, 0, sizeof(p->ext));</span><br><span style="color: hsl(0, 100%, 40%);">- ((struct phone_pvt *)(ast_channel_tech_pvt(ast)))->owner = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- ast_module_unref(ast_module_info->self);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_verb(3, "Hungup '%s'\n", ast_channel_name(ast));</span><br><span style="color: hsl(0, 100%, 40%);">- ast_channel_tech_pvt_set(ast, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_setstate(ast, AST_STATE_DOWN);</span><br><span style="color: hsl(0, 100%, 40%);">- restart_monitor();</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int phone_setup(struct ast_channel *ast)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct phone_pvt *p;</span><br><span style="color: hsl(0, 100%, 40%);">- p = ast_channel_tech_pvt(ast);</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, PHONE_CPT_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- /* Nothing to answering really, just start recording */</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_format_cmp(ast_channel_rawreadformat(ast), ast_format_g729) == AST_FORMAT_CMP_EQUAL) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Prefer g729 */</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, PHONE_REC_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!p->lastinput || (ast_format_cmp(p->lastinput, ast_format_g729) != AST_FORMAT_CMP_EQUAL)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_replace(p->lastinput, ast_format_g729);</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_REC_CODEC, G729)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Failed to set codec to g729\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (ast_format_cmp(ast_channel_rawreadformat(ast), ast_format_g723) == AST_FORMAT_CMP_EQUAL) {</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, PHONE_REC_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!p->lastinput || (ast_format_cmp(p->lastinput, ast_format_g723) != AST_FORMAT_CMP_EQUAL)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_replace(p->lastinput, ast_format_g723);</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_REC_CODEC, G723_63)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Failed to set codec to g723.1\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (ast_format_cmp(ast_channel_rawreadformat(ast), ast_format_slin) == AST_FORMAT_CMP_EQUAL) {</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, PHONE_REC_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!p->lastinput || (ast_format_cmp(p->lastinput, ast_format_slin) != AST_FORMAT_CMP_EQUAL)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_replace(p->lastinput, ast_format_slin);</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_REC_CODEC, LINEAR16)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Failed to set codec to signed linear 16\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (ast_format_cmp(ast_channel_rawreadformat(ast), ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) {</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, PHONE_REC_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!p->lastinput || (ast_format_cmp(p->lastinput, ast_format_ulaw) != AST_FORMAT_CMP_EQUAL)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_replace(p->lastinput, ast_format_ulaw);</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_REC_CODEC, ULAW)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Failed to set codec to uLaw\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (p->mode == MODE_FXS) {</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, PHONE_REC_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!p->lastinput || (ast_format_cmp(p->lastinput, ast_channel_rawreadformat(ast)) == AST_FORMAT_CMP_NOT_EQUAL)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_replace(p->lastinput, ast_channel_rawreadformat(ast));</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_REC_CODEC, ast_channel_rawreadformat(ast))) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Failed to set codec to %s\n",</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_get_name(ast_channel_rawreadformat(ast)));</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Can't do format %s\n", ast_format_get_name(ast_channel_rawreadformat(ast)));</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_REC_START)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Failed to start recording\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- /* set the DTMF times (the default is too short) */</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, PHONE_SET_TONE_ON_TIME, 300);</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, PHONE_SET_TONE_OFF_TIME, 200);</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int phone_answer(struct ast_channel *ast)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct phone_pvt *p;</span><br><span style="color: hsl(0, 100%, 40%);">- p = ast_channel_tech_pvt(ast);</span><br><span style="color: hsl(0, 100%, 40%);">- /* In case it's a LineJack, take it off hook */</span><br><span style="color: hsl(0, 100%, 40%);">- if (p->mode == MODE_FXO) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_PSTN_SET_STATE, PSTN_OFF_HOOK))</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "ioctl(PHONE_PSTN_SET_STATE) failed on %s (%s)\n", ast_channel_name(ast), strerror(errno));</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "Took linejack off hook\n");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- phone_setup(ast);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "phone_answer(%s)\n", ast_channel_name(ast));</span><br><span style="color: hsl(0, 100%, 40%);">- ast_channel_rings_set(ast, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_setstate(ast, AST_STATE_UP);</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-#if 0</span><br><span style="color: hsl(0, 100%, 40%);">-static char phone_2digit(char c)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- if (c == 12)</span><br><span style="color: hsl(0, 100%, 40%);">- return '#';</span><br><span style="color: hsl(0, 100%, 40%);">- else if (c == 11)</span><br><span style="color: hsl(0, 100%, 40%);">- return '*';</span><br><span style="color: hsl(0, 100%, 40%);">- else if ((c < 10) && (c >= 0))</span><br><span style="color: hsl(0, 100%, 40%);">- return '0' + c - 1;</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(0, 100%, 40%);">- return '?';</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ast_frame *phone_exception(struct ast_channel *ast)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- int res;</span><br><span style="color: hsl(0, 100%, 40%);">- union telephony_exception phonee;</span><br><span style="color: hsl(0, 100%, 40%);">- struct phone_pvt *p = ast_channel_tech_pvt(ast);</span><br><span style="color: hsl(0, 100%, 40%);">- char digit;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Some nice norms */</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.datalen = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.samples = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.data.ptr = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.src = "Phone";</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.offset = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.mallocd=0;</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.delivery = ast_tv(0,0);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- phonee.bytes = ioctl(p->fd, PHONE_EXCEPTION);</span><br><span style="color: hsl(0, 100%, 40%);">- if (phonee.bits.dtmf_ready) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "phone_exception(): DTMF\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* We've got a digit -- Just handle this nicely and easily */</span><br><span style="color: hsl(0, 100%, 40%);">- digit = ioctl(p->fd, PHONE_GET_DTMF_ASCII);</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.subclass.integer = digit;</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.frametype = AST_FRAME_DTMF;</span><br><span style="color: hsl(0, 100%, 40%);">- return &p->fr;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (phonee.bits.hookstate) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "Hookstate changed\n");</span><br><span style="color: hsl(0, 100%, 40%);">- res = ioctl(p->fd, PHONE_HOOKSTATE);</span><br><span style="color: hsl(0, 100%, 40%);">- /* See if we've gone on hook, if so, notify by returning NULL */</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "New hookstate: %d\n", res);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!res && (p->mode != MODE_FXO))</span><br><span style="color: hsl(0, 100%, 40%);">- return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- else {</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_channel_state(ast) == AST_STATE_RINGING) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* They've picked up the phone */</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.frametype = AST_FRAME_CONTROL;</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.subclass.integer = AST_CONTROL_ANSWER;</span><br><span style="color: hsl(0, 100%, 40%);">- phone_setup(ast);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_setstate(ast, AST_STATE_UP);</span><br><span style="color: hsl(0, 100%, 40%);">- return &p->fr;</span><br><span style="color: hsl(0, 100%, 40%);">- } else</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Got off hook in weird state %u\n", ast_channel_state(ast));</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-#if 1</span><br><span style="color: hsl(0, 100%, 40%);">- if (phonee.bits.pstn_ring)</span><br><span style="color: hsl(0, 100%, 40%);">- ast_verbose("Unit is ringing\n");</span><br><span style="color: hsl(0, 100%, 40%);">- if (phonee.bits.caller_id) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_verbose("We have caller ID\n");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (phonee.bits.pstn_wink)</span><br><span style="color: hsl(0, 100%, 40%);">- ast_verbose("Detected Wink\n");</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">- /* Strange -- nothing there.. */</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.frametype = AST_FRAME_NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.subclass.integer = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- return &p->fr;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ast_frame *phone_read(struct ast_channel *ast)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- int res;</span><br><span style="color: hsl(0, 100%, 40%);">- struct phone_pvt *p = ast_channel_tech_pvt(ast);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Some nice norms */</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.datalen = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.samples = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.data.ptr = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.src = "Phone";</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.offset = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.mallocd=0;</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.delivery = ast_tv(0,0);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Try to read some data... */</span><br><span style="color: hsl(0, 100%, 40%);">- CHECK_BLOCKING(ast);</span><br><span style="color: hsl(0, 100%, 40%);">- res = read(p->fd, p->buf, PHONE_MAX_BUF);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_clear_flag(ast_channel_flags(ast), AST_FLAG_BLOCKING);</span><br><span style="color: hsl(0, 100%, 40%);">- if (res < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-#if 0</span><br><span style="color: hsl(0, 100%, 40%);">- if (errno == EAGAIN) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Null frame received\n");</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.frametype = AST_FRAME_NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.subclass = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- return &p->fr;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Error reading: %s\n", strerror(errno));</span><br><span style="color: hsl(0, 100%, 40%);">- return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.data.ptr = p->buf;</span><br><span style="color: hsl(0, 100%, 40%);">- if (p->mode != MODE_FXS)</span><br><span style="color: hsl(0, 100%, 40%);">- switch(p->buf[0] & 0x3) {</span><br><span style="color: hsl(0, 100%, 40%);">- case '0':</span><br><span style="color: hsl(0, 100%, 40%);">- case '1':</span><br><span style="color: hsl(0, 100%, 40%);">- /* Normal */</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- case '2':</span><br><span style="color: hsl(0, 100%, 40%);">- case '3':</span><br><span style="color: hsl(0, 100%, 40%);">- /* VAD/CNG, only send two words */</span><br><span style="color: hsl(0, 100%, 40%);">- res = 4;</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.samples = 240;</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.datalen = res;</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.frametype = ast_format_get_type(p->lastinput) == AST_MEDIA_TYPE_AUDIO ?</span><br><span style="color: hsl(0, 100%, 40%);">- AST_FRAME_VOICE : ast_format_get_type(p->lastinput) == AST_MEDIA_TYPE_IMAGE ?</span><br><span style="color: hsl(0, 100%, 40%);">- AST_FRAME_IMAGE : AST_FRAME_VIDEO;</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.subclass.format = p->lastinput;</span><br><span style="color: hsl(0, 100%, 40%);">- p->fr.offset = AST_FRIENDLY_OFFSET;</span><br><span style="color: hsl(0, 100%, 40%);">- /* Byteswap from little-endian to native-endian */</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_format_cmp(p->fr.subclass.format, ast_format_slin) == AST_FORMAT_CMP_EQUAL)</span><br><span style="color: hsl(0, 100%, 40%);">- ast_frame_byteswap_le(&p->fr);</span><br><span style="color: hsl(0, 100%, 40%);">- return &p->fr;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int phone_write_buf(struct phone_pvt *p, const char *buf, int len, int frlen, int swap)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- int res;</span><br><span style="color: hsl(0, 100%, 40%);">- /* Store as much of the buffer as we can, then write fixed frames */</span><br><span style="color: hsl(0, 100%, 40%);">- int space = sizeof(p->obuf) - p->obuflen;</span><br><span style="color: hsl(0, 100%, 40%);">- /* Make sure we have enough buffer space to store the frame */</span><br><span style="color: hsl(0, 100%, 40%);">- if (space < len)</span><br><span style="color: hsl(0, 100%, 40%);">- len = space;</span><br><span style="color: hsl(0, 100%, 40%);">- if (swap)</span><br><span style="color: hsl(0, 100%, 40%);">- ast_swapcopy_samples(p->obuf+p->obuflen, buf, len/2);</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(0, 100%, 40%);">- memcpy(p->obuf + p->obuflen, buf, len);</span><br><span style="color: hsl(0, 100%, 40%);">- p->obuflen += len;</span><br><span style="color: hsl(0, 100%, 40%);">- while(p->obuflen > frlen) {</span><br><span style="color: hsl(0, 100%, 40%);">- res = write(p->fd, p->obuf, frlen);</span><br><span style="color: hsl(0, 100%, 40%);">- if (res != frlen) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (res < 1) {</span><br><span style="color: hsl(0, 100%, 40%);">-/*</span><br><span style="color: hsl(0, 100%, 40%);">- * Card is in non-blocking mode now and it works well now, but there are</span><br><span style="color: hsl(0, 100%, 40%);">- * lot of messages like this. So, this message is temporarily disabled.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Only wrote %d of %d bytes\n", res, frlen);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- p->obuflen -= frlen;</span><br><span style="color: hsl(0, 100%, 40%);">- /* Move memory if necessary */</span><br><span style="color: hsl(0, 100%, 40%);">- if (p->obuflen)</span><br><span style="color: hsl(0, 100%, 40%);">- memmove(p->obuf, p->obuf + frlen, p->obuflen);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- return len;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int phone_send_text(struct ast_channel *ast, const char *text)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- int length = strlen(text);</span><br><span style="color: hsl(0, 100%, 40%);">- return phone_write_buf(ast_channel_tech_pvt(ast), text, length, length, 0) ==</span><br><span style="color: hsl(0, 100%, 40%);">- length ? 0 : -1;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int phone_write(struct ast_channel *ast, struct ast_frame *frame)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct phone_pvt *p = ast_channel_tech_pvt(ast);</span><br><span style="color: hsl(0, 100%, 40%);">- int res;</span><br><span style="color: hsl(0, 100%, 40%);">- int maxfr=0;</span><br><span style="color: hsl(0, 100%, 40%);">- char *pos;</span><br><span style="color: hsl(0, 100%, 40%);">- int sofar;</span><br><span style="color: hsl(0, 100%, 40%);">- int expected;</span><br><span style="color: hsl(0, 100%, 40%);">- int codecset = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- char tmpbuf[4];</span><br><span style="color: hsl(0, 100%, 40%);">- /* Write a frame of (presumably voice) data */</span><br><span style="color: hsl(0, 100%, 40%);">- if (frame->frametype != AST_FRAME_VOICE && p->mode != MODE_FXS) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (frame->frametype != AST_FRAME_IMAGE)</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Don't know what to do with frame type '%u'\n", frame->frametype);</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-#if 0</span><br><span style="color: hsl(0, 100%, 40%);">- /* If we're not in up mode, go into up mode now */</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast->_state != AST_STATE_UP) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_setstate(ast, AST_STATE_UP);</span><br><span style="color: hsl(0, 100%, 40%);">- phone_setup(ast);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-#else</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_channel_state(ast) != AST_STATE_UP) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Don't try tos end audio on-hook */</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_format_cmp(frame->subclass.format, ast_format_g729) == AST_FORMAT_CMP_EQUAL) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (!p->lastformat || (ast_format_cmp(p->lastformat, ast_format_g729) != AST_FORMAT_CMP_EQUAL)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, PHONE_PLAY_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, PHONE_REC_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_PLAY_CODEC, G729)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unable to set G729 mode\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_REC_CODEC, G729)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unable to set G729 mode\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_replace(p->lastformat, ast_format_g729);</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_replace(p->lastinput, ast_format_g729);</span><br><span style="color: hsl(0, 100%, 40%);">- /* Reset output buffer */</span><br><span style="color: hsl(0, 100%, 40%);">- p->obuflen = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- codecset = 1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (frame->datalen > 80) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Frame size too large for G.729 (%d bytes)\n", frame->datalen);</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- maxfr = 80;</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (ast_format_cmp(frame->subclass.format, ast_format_g723) == AST_FORMAT_CMP_EQUAL) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (!p->lastformat || (ast_format_cmp(p->lastformat, ast_format_g723) != AST_FORMAT_CMP_EQUAL)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, PHONE_PLAY_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, PHONE_REC_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_PLAY_CODEC, G723_63)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unable to set G723.1 mode\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_REC_CODEC, G723_63)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unable to set G723.1 mode\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_replace(p->lastformat, ast_format_g723);</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_replace(p->lastinput, ast_format_g723);</span><br><span style="color: hsl(0, 100%, 40%);">- /* Reset output buffer */</span><br><span style="color: hsl(0, 100%, 40%);">- p->obuflen = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- codecset = 1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (frame->datalen > 24) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Frame size too large for G.723.1 (%d bytes)\n", frame->datalen);</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- maxfr = 24;</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (ast_format_cmp(frame->subclass.format, ast_format_slin) == AST_FORMAT_CMP_EQUAL) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (!p->lastformat || (ast_format_cmp(p->lastformat, ast_format_slin) != AST_FORMAT_CMP_EQUAL)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, PHONE_PLAY_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, PHONE_REC_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_PLAY_CODEC, LINEAR16)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unable to set 16-bit linear mode\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_REC_CODEC, LINEAR16)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unable to set 16-bit linear mode\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_replace(p->lastformat, ast_format_slin);</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_replace(p->lastinput, ast_format_slin);</span><br><span style="color: hsl(0, 100%, 40%);">- codecset = 1;</span><br><span style="color: hsl(0, 100%, 40%);">- /* Reset output buffer */</span><br><span style="color: hsl(0, 100%, 40%);">- p->obuflen = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- maxfr = 480;</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (ast_format_cmp(frame->subclass.format, ast_format_ulaw) == AST_FORMAT_CMP_EQUAL) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (!p->lastformat || (ast_format_cmp(p->lastformat, ast_format_ulaw) != AST_FORMAT_CMP_EQUAL)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, PHONE_PLAY_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, PHONE_REC_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_PLAY_CODEC, ULAW)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unable to set uLaw mode\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_REC_CODEC, ULAW)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unable to set uLaw mode\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_replace(p->lastformat, ast_format_ulaw);</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_replace(p->lastinput, ast_format_ulaw);</span><br><span style="color: hsl(0, 100%, 40%);">- codecset = 1;</span><br><span style="color: hsl(0, 100%, 40%);">- /* Reset output buffer */</span><br><span style="color: hsl(0, 100%, 40%);">- p->obuflen = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- maxfr = 240;</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- if (!p->lastformat || (ast_format_cmp(p->lastformat, frame->subclass.format) != AST_FORMAT_CMP_EQUAL)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, PHONE_PLAY_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, PHONE_REC_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_PLAY_CODEC, ast_format_compatibility_format2bitfield(frame->subclass.format))) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unable to set %s mode\n",</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_get_name(frame->subclass.format));</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_REC_CODEC, ast_format_compatibility_format2bitfield(frame->subclass.format))) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unable to set %s mode\n",</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_get_name(frame->subclass.format));</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_replace(p->lastformat, frame->subclass.format);</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_replace(p->lastinput, frame->subclass.format);</span><br><span style="color: hsl(0, 100%, 40%);">- codecset = 1;</span><br><span style="color: hsl(0, 100%, 40%);">- /* Reset output buffer */</span><br><span style="color: hsl(0, 100%, 40%);">- p->obuflen = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- maxfr = 480;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (codecset) {</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, PHONE_REC_DEPTH, 3);</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(p->fd, PHONE_PLAY_DEPTH, 3);</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_PLAY_START)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Failed to start playback\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(p->fd, PHONE_REC_START)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Failed to start recording\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- /* If we get here, we have a frame of Appropriate data */</span><br><span style="color: hsl(0, 100%, 40%);">- sofar = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- pos = frame->data.ptr;</span><br><span style="color: hsl(0, 100%, 40%);">- while(sofar < frame->datalen) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Write in no more than maxfr sized frames */</span><br><span style="color: hsl(0, 100%, 40%);">- expected = frame->datalen - sofar;</span><br><span style="color: hsl(0, 100%, 40%);">- if (maxfr < expected)</span><br><span style="color: hsl(0, 100%, 40%);">- expected = maxfr;</span><br><span style="color: hsl(0, 100%, 40%);">- /* XXX Internet Phone Jack does not handle the 4-byte VAD frame properly! XXX</span><br><span style="color: hsl(0, 100%, 40%);">- we have to pad it to 24 bytes still. */</span><br><span style="color: hsl(0, 100%, 40%);">- if (frame->datalen == 4) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (p->silencesupression) {</span><br><span style="color: hsl(0, 100%, 40%);">- memcpy(tmpbuf, frame->data.ptr, 4);</span><br><span style="color: hsl(0, 100%, 40%);">- expected = 24;</span><br><span style="color: hsl(0, 100%, 40%);">- res = phone_write_buf(p, tmpbuf, expected, maxfr, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- res = 4;</span><br><span style="color: hsl(0, 100%, 40%);">- expected=4;</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- int swap = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-#if __BYTE_ORDER == __BIG_ENDIAN</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_format_cmp(frame->subclass.format, ast_format_slin) == AST_FORMAT_CMP_EQUAL)</span><br><span style="color: hsl(0, 100%, 40%);">- swap = 1; /* Swap big-endian samples to little-endian as we copy */</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">- res = phone_write_buf(p, pos, expected, maxfr, swap);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (res != expected) {</span><br><span style="color: hsl(0, 100%, 40%);">- if ((errno != EAGAIN) && (errno != EINTR)) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (res < 0)</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Write returned error (%s)\n", strerror(errno));</span><br><span style="color: hsl(0, 100%, 40%);">- /*</span><br><span style="color: hsl(0, 100%, 40%);">- * Card is in non-blocking mode now and it works well now, but there are</span><br><span style="color: hsl(0, 100%, 40%);">- * lot of messages like this. So, this message is temporarily disabled.</span><br><span style="color: hsl(0, 100%, 40%);">- */</span><br><span style="color: hsl(0, 100%, 40%);">-#if 0</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Only wrote %d of %d bytes\n", res, frame->datalen);</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- } else /* Pretend it worked */</span><br><span style="color: hsl(0, 100%, 40%);">- res = expected;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- sofar += res;</span><br><span style="color: hsl(0, 100%, 40%);">- pos += res;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *cntx, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_format_cap *caps = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_channel *tmp;</span><br><span style="color: hsl(0, 100%, 40%);">- struct phone_codec_data queried_codec;</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_format *tmpfmt;</span><br><span style="color: hsl(0, 100%, 40%);">- caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);</span><br><span style="color: hsl(0, 100%, 40%);">- tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "", i->ext, i->context, assignedids, requestor, 0, "Phone/%s", i->dev + 5);</span><br><span style="color: hsl(0, 100%, 40%);">- if (tmp && caps) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_channel_lock(tmp);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_channel_tech_set(tmp, cur_tech);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_channel_set_fd(tmp, 0, i->fd);</span><br><span style="color: hsl(0, 100%, 40%);">- /* XXX Switching formats silently causes kernel panics XXX */</span><br><span style="color: hsl(0, 100%, 40%);">- if (i->mode == MODE_FXS &&</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(i->fd, PHONE_QUERY_CODEC, &queried_codec) == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (queried_codec.type == LINEAR16) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_cap_append(caps, ast_format_slin, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_cap_remove(prefcap, ast_format_slin);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_cap_append_from_cap(caps, prefcap, AST_MEDIA_TYPE_UNKNOWN);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_cap_append_from_cap(caps, prefcap, AST_MEDIA_TYPE_UNKNOWN);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- tmpfmt = ast_format_cap_get_format(caps, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_channel_nativeformats_set(tmp, caps);</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_ref(caps, -1);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_channel_set_rawreadformat(tmp, tmpfmt);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_channel_set_rawwriteformat(tmp, tmpfmt);</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_ref(tmpfmt, -1);</span><br><span style="color: hsl(0, 100%, 40%);">- /* no need to call ast_setstate: the channel_alloc already did its job */</span><br><span style="color: hsl(0, 100%, 40%);">- if (state == AST_STATE_RING)</span><br><span style="color: hsl(0, 100%, 40%);">- ast_channel_rings_set(tmp, 1);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_channel_tech_pvt_set(tmp, i);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_channel_context_set(tmp, cntx);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!ast_strlen_zero(i->ext))</span><br><span style="color: hsl(0, 100%, 40%);">- ast_channel_exten_set(tmp, i->ext);</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(0, 100%, 40%);">- ast_channel_exten_set(tmp, "s");</span><br><span style="color: hsl(0, 100%, 40%);">- if (!ast_strlen_zero(i->language))</span><br><span style="color: hsl(0, 100%, 40%);">- ast_channel_language_set(tmp, i->language);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Don't use ast_set_callerid() here because it will</span><br><span style="color: hsl(0, 100%, 40%);">- * generate a NewCallerID event before the NewChannel event */</span><br><span style="color: hsl(0, 100%, 40%);">- if (!ast_strlen_zero(i->cid_num)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_channel_caller(tmp)->ani.number.valid = 1;</span><br><span style="color: hsl(0, 100%, 40%);">- ast_channel_caller(tmp)->ani.number.str = ast_strdup(i->cid_num);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- i->owner = tmp;</span><br><span style="color: hsl(0, 100%, 40%);">- ast_module_ref(ast_module_info->self);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_channel_unlock(tmp);</span><br><span style="color: hsl(0, 100%, 40%);">- if (state != AST_STATE_DOWN) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (state == AST_STATE_RING) {</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(ast_channel_fd(tmp, 0), PHONE_RINGBACK);</span><br><span style="color: hsl(0, 100%, 40%);">- i->cpt = 1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_pbx_start(tmp)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unable to start PBX on %s\n", ast_channel_name(tmp));</span><br><span style="color: hsl(0, 100%, 40%);">- ast_hangup(tmp);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_cleanup(caps);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unable to allocate channel structure\n");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- return tmp;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void phone_mini_packet(struct phone_pvt *i)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- int res;</span><br><span style="color: hsl(0, 100%, 40%);">- char buf[1024];</span><br><span style="color: hsl(0, 100%, 40%);">- /* Ignore stuff we read... */</span><br><span style="color: hsl(0, 100%, 40%);">- res = read(i->fd, buf, sizeof(buf));</span><br><span style="color: hsl(0, 100%, 40%);">- if (res < 1) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Read returned %d: %s\n", res, strerror(errno));</span><br><span style="color: hsl(0, 100%, 40%);">- return;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void phone_check_exception(struct phone_pvt *i)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- int offhook=0;</span><br><span style="color: hsl(0, 100%, 40%);">- char digit[2] = {0 , 0};</span><br><span style="color: hsl(0, 100%, 40%);">- union telephony_exception phonee;</span><br><span style="color: hsl(0, 100%, 40%);">- /* XXX Do something XXX */</span><br><span style="color: hsl(0, 100%, 40%);">-#if 0</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "Exception!\n");</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">- phonee.bytes = ioctl(i->fd, PHONE_EXCEPTION);</span><br><span style="color: hsl(0, 100%, 40%);">- if (phonee.bits.dtmf_ready) {</span><br><span style="color: hsl(0, 100%, 40%);">- digit[0] = ioctl(i->fd, PHONE_GET_DTMF_ASCII);</span><br><span style="color: hsl(0, 100%, 40%);">- if (i->mode == MODE_DIALTONE || i->mode == MODE_FXS || i->mode == MODE_SIGMA) {</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(i->fd, PHONE_PLAY_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(i->fd, PHONE_REC_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(i->fd, PHONE_CPT_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- i->dialtone = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- if (strlen(i->ext) < AST_MAX_EXTENSION - 1)</span><br><span style="color: hsl(0, 100%, 40%);">- strncat(i->ext, digit, sizeof(i->ext) - strlen(i->ext) - 1);</span><br><span style="color: hsl(0, 100%, 40%);">- if ((i->mode != MODE_FXS ||</span><br><span style="color: hsl(0, 100%, 40%);">- !(phonee.bytes = ioctl(i->fd, PHONE_EXCEPTION)) ||</span><br><span style="color: hsl(0, 100%, 40%);">- !phonee.bits.dtmf_ready) &&</span><br><span style="color: hsl(0, 100%, 40%);">- ast_exists_extension(NULL, i->context, i->ext, 1, i->cid_num)) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* It's a valid extension in its context, get moving! */</span><br><span style="color: hsl(0, 100%, 40%);">- phone_new(i, AST_STATE_RING, i->context, NULL, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">- /* No need to restart monitor, we are the monitor */</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!ast_canmatch_extension(NULL, i->context, i->ext, 1, i->cid_num)) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* There is nothing in the specified extension that can match anymore.</span><br><span style="color: hsl(0, 100%, 40%);">- Try the default */</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_exists_extension(NULL, "default", i->ext, 1, i->cid_num)) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Check the default, too... */</span><br><span style="color: hsl(0, 100%, 40%);">- phone_new(i, AST_STATE_RING, "default", NULL, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">- /* XXX This should probably be justified better XXX */</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!ast_canmatch_extension(NULL, "default", i->ext, 1, i->cid_num)) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* It's not a valid extension, give a busy signal */</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "%s can't match anything in %s or default\n", i->ext, i->context);</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(i->fd, PHONE_BUSY);</span><br><span style="color: hsl(0, 100%, 40%);">- i->cpt = 1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-#if 0</span><br><span style="color: hsl(0, 100%, 40%);">- ast_verbose("Extension is %s\n", i->ext);</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (phonee.bits.hookstate) {</span><br><span style="color: hsl(0, 100%, 40%);">- offhook = ioctl(i->fd, PHONE_HOOKSTATE);</span><br><span style="color: hsl(0, 100%, 40%);">- if (offhook) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (i->mode == MODE_IMMEDIATE) {</span><br><span style="color: hsl(0, 100%, 40%);">- phone_new(i, AST_STATE_RING, i->context, NULL, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (i->mode == MODE_DIALTONE) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_module_ref(ast_module_info->self);</span><br><span style="color: hsl(0, 100%, 40%);">- /* Reset the extension */</span><br><span style="color: hsl(0, 100%, 40%);">- i->ext[0] = '\0';</span><br><span style="color: hsl(0, 100%, 40%);">- /* Play the dialtone */</span><br><span style="color: hsl(0, 100%, 40%);">- i->dialtone++;</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(i->fd, PHONE_PLAY_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(i->fd, PHONE_PLAY_CODEC, ULAW);</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(i->fd, PHONE_PLAY_START);</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_cleanup(i->lastformat);</span><br><span style="color: hsl(0, 100%, 40%);">- i->lastformat = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (i->mode == MODE_SIGMA) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_module_ref(ast_module_info->self);</span><br><span style="color: hsl(0, 100%, 40%);">- /* Reset the extension */</span><br><span style="color: hsl(0, 100%, 40%);">- i->ext[0] = '\0';</span><br><span style="color: hsl(0, 100%, 40%);">- /* Play the dialtone */</span><br><span style="color: hsl(0, 100%, 40%);">- i->dialtone++;</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(i->fd, PHONE_DIALTONE);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- if (i->dialtone)</span><br><span style="color: hsl(0, 100%, 40%);">- ast_module_unref(ast_module_info->self);</span><br><span style="color: hsl(0, 100%, 40%);">- memset(i->ext, 0, sizeof(i->ext));</span><br><span style="color: hsl(0, 100%, 40%);">- if (i->cpt)</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(i->fd, PHONE_CPT_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- i->cpt = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(i->fd, PHONE_PLAY_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(i->fd, PHONE_REC_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- i->dialtone = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_cleanup(i->lastformat);</span><br><span style="color: hsl(0, 100%, 40%);">- i->lastformat = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (phonee.bits.pstn_ring) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_verbose("Unit is ringing\n");</span><br><span style="color: hsl(0, 100%, 40%);">- phone_new(i, AST_STATE_RING, i->context, NULL, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (phonee.bits.caller_id)</span><br><span style="color: hsl(0, 100%, 40%);">- ast_verbose("We have caller ID\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static void *do_monitor(void *data)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct pollfd *fds = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- int nfds = 0, inuse_fds = 0, res;</span><br><span style="color: hsl(0, 100%, 40%);">- struct phone_pvt *i;</span><br><span style="color: hsl(0, 100%, 40%);">- int tonepos = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- /* The tone we're playing this round */</span><br><span style="color: hsl(0, 100%, 40%);">- struct timeval to = { 0, 0 };</span><br><span style="color: hsl(0, 100%, 40%);">- int dotone;</span><br><span style="color: hsl(0, 100%, 40%);">- /* This thread monitors all the frame relay interfaces which are not yet in use</span><br><span style="color: hsl(0, 100%, 40%);">- (and thus do not have a separate thread) indefinitely */</span><br><span style="color: hsl(0, 100%, 40%);">- while (monitor) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Don't let anybody kill us right away. Nobody should lock the interface list</span><br><span style="color: hsl(0, 100%, 40%);">- and wait for the monitor list, but the other way around is okay. */</span><br><span style="color: hsl(0, 100%, 40%);">- /* Lock the interface list */</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_mutex_lock(&iflock)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "Unable to grab interface lock\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- /* Build the stuff we're going to select on, that is the socket of every</span><br><span style="color: hsl(0, 100%, 40%);">- phone_pvt that does not have an associated owner channel */</span><br><span style="color: hsl(0, 100%, 40%);">- i = iflist;</span><br><span style="color: hsl(0, 100%, 40%);">- dotone = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- inuse_fds = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- for (i = iflist; i; i = i->next) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (!i->owner) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* This needs to be watched, as it lacks an owner */</span><br><span style="color: hsl(0, 100%, 40%);">- if (inuse_fds == nfds) {</span><br><span style="color: hsl(0, 100%, 40%);">- void *tmp = ast_realloc(fds, (nfds + 1) * sizeof(*fds));</span><br><span style="color: hsl(0, 100%, 40%);">- if (!tmp) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Avoid leaking */</span><br><span style="color: hsl(0, 100%, 40%);">- continue;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- fds = tmp;</span><br><span style="color: hsl(0, 100%, 40%);">- nfds++;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- fds[inuse_fds].fd = i->fd;</span><br><span style="color: hsl(0, 100%, 40%);">- fds[inuse_fds].events = POLLIN | POLLERR;</span><br><span style="color: hsl(0, 100%, 40%);">- fds[inuse_fds].revents = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- inuse_fds++;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (i->dialtone && i->mode != MODE_SIGMA) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Remember we're going to have to come back and play</span><br><span style="color: hsl(0, 100%, 40%);">- more dialtones */</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_tvzero(to)) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* If we're due for a dialtone, play one */</span><br><span style="color: hsl(0, 100%, 40%);">- if (write(i->fd, DialTone + tonepos, 240) != 240) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Dial tone write error\n");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- dotone++;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- /* Okay, now that we know what to do, release the interface lock */</span><br><span style="color: hsl(0, 100%, 40%);">- ast_mutex_unlock(&iflock);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Wait indefinitely for something to happen */</span><br><span style="color: hsl(0, 100%, 40%);">- if (dotone && i && i->mode != MODE_SIGMA) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* If we're ready to recycle the time, set it to 30 ms */</span><br><span style="color: hsl(0, 100%, 40%);">- tonepos += 240;</span><br><span style="color: hsl(0, 100%, 40%);">- if (tonepos >= sizeof(DialTone)) {</span><br><span style="color: hsl(0, 100%, 40%);">- tonepos = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_tvzero(to)) {</span><br><span style="color: hsl(0, 100%, 40%);">- to = ast_tv(0, 30000);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- res = ast_poll2(fds, inuse_fds, &to);</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- res = ast_poll(fds, inuse_fds, -1);</span><br><span style="color: hsl(0, 100%, 40%);">- to = ast_tv(0, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- tonepos = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- /* Okay, select has finished. Let's see what happened. */</span><br><span style="color: hsl(0, 100%, 40%);">- if (res < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "poll returned %d: %s\n", res, strerror(errno));</span><br><span style="color: hsl(0, 100%, 40%);">- continue;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- /* If there are no fd's changed, just continue, it's probably time</span><br><span style="color: hsl(0, 100%, 40%);">- to play some more dialtones */</span><br><span style="color: hsl(0, 100%, 40%);">- if (!res) {</span><br><span style="color: hsl(0, 100%, 40%);">- continue;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- /* Alright, lock the interface list again, and let's look and see what has</span><br><span style="color: hsl(0, 100%, 40%);">- happened */</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_mutex_lock(&iflock)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unable to lock the interface list\n");</span><br><span style="color: hsl(0, 100%, 40%);">- continue;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- for (i = iflist; i; i = i->next) {</span><br><span style="color: hsl(0, 100%, 40%);">- int j;</span><br><span style="color: hsl(0, 100%, 40%);">- /* Find the record */</span><br><span style="color: hsl(0, 100%, 40%);">- for (j = 0; j < inuse_fds; j++) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (fds[j].fd == i->fd) {</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Not found? */</span><br><span style="color: hsl(0, 100%, 40%);">- if (j == inuse_fds) {</span><br><span style="color: hsl(0, 100%, 40%);">- continue;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (fds[j].revents & POLLIN) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (i->owner) {</span><br><span style="color: hsl(0, 100%, 40%);">- continue;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- phone_mini_packet(i);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (fds[j].revents & POLLERR) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (i->owner) {</span><br><span style="color: hsl(0, 100%, 40%);">- continue;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- phone_check_exception(i);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ast_mutex_unlock(&iflock);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int restart_monitor()</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- /* If we're supposed to be stopped -- stay stopped */</span><br><span style="color: hsl(0, 100%, 40%);">- if (monitor_thread == AST_PTHREADT_STOP)</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_mutex_lock(&monlock)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unable to lock monitor\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (monitor_thread == pthread_self()) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_mutex_unlock(&monlock);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Cannot kill myself\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (monitor_thread != AST_PTHREADT_NULL) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_mutex_lock(&iflock)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_mutex_unlock(&monlock);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unable to lock the interface list\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- monitor = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- while (pthread_kill(monitor_thread, SIGURG) == 0)</span><br><span style="color: hsl(0, 100%, 40%);">- sched_yield();</span><br><span style="color: hsl(0, 100%, 40%);">- pthread_join(monitor_thread, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_mutex_unlock(&iflock);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- monitor = 1;</span><br><span style="color: hsl(0, 100%, 40%);">- /* Start a new monitor */</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_mutex_unlock(&monlock);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "Unable to start monitor thread.\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ast_mutex_unlock(&monlock);</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct phone_pvt *mkif(const char *iface, int mode, int txgain, int rxgain)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- /* Make a phone_pvt structure for this interface */</span><br><span style="color: hsl(0, 100%, 40%);">- struct phone_pvt *tmp;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- tmp = ast_calloc(1, sizeof(*tmp));</span><br><span style="color: hsl(0, 100%, 40%);">- if (tmp) {</span><br><span style="color: hsl(0, 100%, 40%);">- tmp->fd = open(iface, O_RDWR);</span><br><span style="color: hsl(0, 100%, 40%);">- if (tmp->fd < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unable to open '%s'\n", iface);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_free(tmp);</span><br><span style="color: hsl(0, 100%, 40%);">- return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (mode == MODE_FXO) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(tmp->fd, IXJCTL_PORT, PORT_PSTN)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "Unable to set port to PSTN\n");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(tmp->fd, IXJCTL_PORT, PORT_POTS))</span><br><span style="color: hsl(0, 100%, 40%);">- if (mode != MODE_FXS)</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "Unable to set port to POTS\n");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(tmp->fd, PHONE_PLAY_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(tmp->fd, PHONE_REC_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(tmp->fd, PHONE_RING_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(tmp->fd, PHONE_CPT_STOP);</span><br><span style="color: hsl(0, 100%, 40%);">- if (ioctl(tmp->fd, PHONE_PSTN_SET_STATE, PSTN_ON_HOOK))</span><br><span style="color: hsl(0, 100%, 40%);">- ast_debug(1, "ioctl(PHONE_PSTN_SET_STATE) failed on %s (%s)\n",iface, strerror(errno));</span><br><span style="color: hsl(0, 100%, 40%);">- if (echocancel != AEC_OFF)</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(tmp->fd, IXJCTL_AEC_START, echocancel);</span><br><span style="color: hsl(0, 100%, 40%);">- if (silencesupression)</span><br><span style="color: hsl(0, 100%, 40%);">- tmp->silencesupression = 1;</span><br><span style="color: hsl(0, 100%, 40%);">-#ifdef PHONE_VAD</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(tmp->fd, PHONE_VAD, tmp->silencesupression);</span><br><span style="color: hsl(0, 100%, 40%);">-#endif</span><br><span style="color: hsl(0, 100%, 40%);">- tmp->mode = mode;</span><br><span style="color: hsl(0, 100%, 40%);">- ast_fd_set_flags(tmp->fd, O_NONBLOCK);</span><br><span style="color: hsl(0, 100%, 40%);">- tmp->owner = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_cleanup(tmp->lastformat);</span><br><span style="color: hsl(0, 100%, 40%);">- tmp->lastformat = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_cleanup(tmp->lastinput);</span><br><span style="color: hsl(0, 100%, 40%);">- tmp->lastinput = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- tmp->ministate = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- memset(tmp->ext, 0, sizeof(tmp->ext));</span><br><span style="color: hsl(0, 100%, 40%);">- ast_copy_string(tmp->language, language, sizeof(tmp->language));</span><br><span style="color: hsl(0, 100%, 40%);">- ast_copy_string(tmp->dev, iface, sizeof(tmp->dev));</span><br><span style="color: hsl(0, 100%, 40%);">- ast_copy_string(tmp->context, context, sizeof(tmp->context));</span><br><span style="color: hsl(0, 100%, 40%);">- tmp->next = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- tmp->obuflen = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- tmp->dialtone = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- tmp->cpt = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- ast_copy_string(tmp->cid_num, cid_num, sizeof(tmp->cid_num));</span><br><span style="color: hsl(0, 100%, 40%);">- ast_copy_string(tmp->cid_name, cid_name, sizeof(tmp->cid_name));</span><br><span style="color: hsl(0, 100%, 40%);">- tmp->txgain = txgain;</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(tmp->fd, PHONE_PLAY_VOLUME, tmp->txgain);</span><br><span style="color: hsl(0, 100%, 40%);">- tmp->rxgain = rxgain;</span><br><span style="color: hsl(0, 100%, 40%);">- ioctl(tmp->fd, PHONE_REC_VOLUME, tmp->rxgain);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- return tmp;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static struct ast_channel *phone_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct phone_pvt *p;</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_channel *tmp = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- const char *name = data;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Search for an unowned channel */</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_mutex_lock(&iflock)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "Unable to lock interface list???\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- p = iflist;</span><br><span style="color: hsl(0, 100%, 40%);">- while(p) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (p->mode == MODE_FXS || (ast_format_cap_iscompatible(cap, phone_tech.capabilities))) {</span><br><span style="color: hsl(0, 100%, 40%);">- size_t length = strlen(p->dev + 5);</span><br><span style="color: hsl(0, 100%, 40%);">- if (strncmp(name, p->dev + 5, length) == 0 &&</span><br><span style="color: hsl(0, 100%, 40%);">- !isalnum(name[length])) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (!p->owner) {</span><br><span style="color: hsl(0, 100%, 40%);">- tmp = phone_new(p, AST_STATE_DOWN, p->context, assignedids, requestor);</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- } else</span><br><span style="color: hsl(0, 100%, 40%);">- *cause = AST_CAUSE_BUSY;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- p = p->next;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ast_mutex_unlock(&iflock);</span><br><span style="color: hsl(0, 100%, 40%);">- restart_monitor();</span><br><span style="color: hsl(0, 100%, 40%);">- if (tmp == NULL) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (!(ast_format_cap_iscompatible(cap, phone_tech.capabilities))) {</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_str *codec_buf = ast_str_alloca(AST_FORMAT_CAP_NAMES_LEN);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n",</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_cap_get_names(cap, &codec_buf));</span><br><span style="color: hsl(0, 100%, 40%);">- return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- return tmp;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* parse gain value from config file */</span><br><span style="color: hsl(0, 100%, 40%);">-static int parse_gain_value(const char *gain_type, const char *value)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- float gain;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* try to scan number */</span><br><span style="color: hsl(0, 100%, 40%);">- if (sscanf(value, "%30f", &gain) != 1)</span><br><span style="color: hsl(0, 100%, 40%);">- {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "Invalid %s value '%s' in '%s' config\n",</span><br><span style="color: hsl(0, 100%, 40%);">- value, gain_type, config);</span><br><span style="color: hsl(0, 100%, 40%);">- return DEFAULT_GAIN;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* multiplicate gain by 1.0 gain value */</span><br><span style="color: hsl(0, 100%, 40%);">- gain = gain * (float)DEFAULT_GAIN;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* percentage? */</span><br><span style="color: hsl(0, 100%, 40%);">- if (value[strlen(value) - 1] == '%')</span><br><span style="color: hsl(0, 100%, 40%);">- return (int)(gain / (float)100);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return (int)gain;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int __unload_module(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct phone_pvt *p, *pl;</span><br><span style="color: hsl(0, 100%, 40%);">- /* First, take us out of the channel loop */</span><br><span style="color: hsl(0, 100%, 40%);">- if (cur_tech)</span><br><span style="color: hsl(0, 100%, 40%);">- ast_channel_unregister(cur_tech);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!ast_mutex_lock(&iflock)) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Hangup all interfaces if they have an owner */</span><br><span style="color: hsl(0, 100%, 40%);">- p = iflist;</span><br><span style="color: hsl(0, 100%, 40%);">- while(p) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (p->owner)</span><br><span style="color: hsl(0, 100%, 40%);">- ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);</span><br><span style="color: hsl(0, 100%, 40%);">- p = p->next;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- iflist = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- ast_mutex_unlock(&iflock);</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unable to lock the monitor\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (!ast_mutex_lock(&monlock)) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (monitor_thread > AST_PTHREADT_NULL) {</span><br><span style="color: hsl(0, 100%, 40%);">- monitor = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- while (pthread_kill(monitor_thread, SIGURG) == 0)</span><br><span style="color: hsl(0, 100%, 40%);">- sched_yield();</span><br><span style="color: hsl(0, 100%, 40%);">- pthread_join(monitor_thread, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- monitor_thread = AST_PTHREADT_STOP;</span><br><span style="color: hsl(0, 100%, 40%);">- ast_mutex_unlock(&monlock);</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unable to lock the monitor\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!ast_mutex_lock(&iflock)) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Destroy all the interfaces and free their memory */</span><br><span style="color: hsl(0, 100%, 40%);">- p = iflist;</span><br><span style="color: hsl(0, 100%, 40%);">- while(p) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Close the socket, assuming it's real */</span><br><span style="color: hsl(0, 100%, 40%);">- if (p->fd > -1)</span><br><span style="color: hsl(0, 100%, 40%);">- close(p->fd);</span><br><span style="color: hsl(0, 100%, 40%);">- pl = p;</span><br><span style="color: hsl(0, 100%, 40%);">- p = p->next;</span><br><span style="color: hsl(0, 100%, 40%);">- /* Free associated memory */</span><br><span style="color: hsl(0, 100%, 40%);">- ast_free(pl);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- iflist = NULL;</span><br><span style="color: hsl(0, 100%, 40%);">- ast_mutex_unlock(&iflock);</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unable to lock the monitor\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return -1;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_ref(phone_tech.capabilities, -1);</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_ref(phone_tech_fxs.capabilities, -1);</span><br><span style="color: hsl(0, 100%, 40%);">- ao2_ref(prefcap, -1);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int unload_module(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- return __unload_module();</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-static int load_module(void)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_config *cfg;</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_variable *v;</span><br><span style="color: hsl(0, 100%, 40%);">- struct phone_pvt *tmp;</span><br><span style="color: hsl(0, 100%, 40%);">- int mode = MODE_IMMEDIATE;</span><br><span style="color: hsl(0, 100%, 40%);">- int txgain = DEFAULT_GAIN, rxgain = DEFAULT_GAIN; /* default gain 1.0 */</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_flags config_flags = { 0 };</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!(phone_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {</span><br><span style="color: hsl(0, 100%, 40%);">- return AST_MODULE_LOAD_DECLINE;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_cap_append(phone_tech.capabilities, ast_format_g723, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_cap_append(phone_tech.capabilities, ast_format_slin, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_cap_append(phone_tech.capabilities, ast_format_ulaw, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_cap_append(phone_tech.capabilities, ast_format_g729, 0);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!(prefcap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {</span><br><span style="color: hsl(0, 100%, 40%);">- return AST_MODULE_LOAD_DECLINE;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_cap_append_from_cap(prefcap, phone_tech.capabilities, AST_MEDIA_TYPE_UNKNOWN);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!(phone_tech_fxs.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {</span><br><span style="color: hsl(0, 100%, 40%);">- return AST_MODULE_LOAD_DECLINE;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if ((cfg = ast_config_load(config, config_flags)) == CONFIG_STATUS_FILEINVALID) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", config);</span><br><span style="color: hsl(0, 100%, 40%);">- return AST_MODULE_LOAD_DECLINE;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* We *must* have a config file otherwise stop immediately */</span><br><span style="color: hsl(0, 100%, 40%);">- if (!cfg) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "Unable to load config %s\n", config);</span><br><span style="color: hsl(0, 100%, 40%);">- return AST_MODULE_LOAD_DECLINE;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_mutex_lock(&iflock)) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* It's a little silly to lock it, but we mind as well just to be sure */</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "Unable to lock interface list???\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return AST_MODULE_LOAD_DECLINE;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- v = ast_variable_browse(cfg, "interfaces");</span><br><span style="color: hsl(0, 100%, 40%);">- while(v) {</span><br><span style="color: hsl(0, 100%, 40%);">- /* Create the interface list */</span><br><span style="color: hsl(0, 100%, 40%);">- if (!strcasecmp(v->name, "device")) {</span><br><span style="color: hsl(0, 100%, 40%);">- tmp = mkif(v->value, mode, txgain, rxgain);</span><br><span style="color: hsl(0, 100%, 40%);">- if (tmp) {</span><br><span style="color: hsl(0, 100%, 40%);">- tmp->next = iflist;</span><br><span style="color: hsl(0, 100%, 40%);">- iflist = tmp;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "Unable to register channel '%s'\n", v->value);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_config_destroy(cfg);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_mutex_unlock(&iflock);</span><br><span style="color: hsl(0, 100%, 40%);">- __unload_module();</span><br><span style="color: hsl(0, 100%, 40%);">- return AST_MODULE_LOAD_DECLINE;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!strcasecmp(v->name, "silencesupression")) {</span><br><span style="color: hsl(0, 100%, 40%);">- silencesupression = ast_true(v->value);</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!strcasecmp(v->name, "language")) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_copy_string(language, v->value, sizeof(language));</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!strcasecmp(v->name, "callerid")) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_callerid_split(v->value, cid_name, sizeof(cid_name), cid_num, sizeof(cid_num));</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!strcasecmp(v->name, "mode")) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (!strncasecmp(v->value, "di", 2))</span><br><span style="color: hsl(0, 100%, 40%);">- mode = MODE_DIALTONE;</span><br><span style="color: hsl(0, 100%, 40%);">- else if (!strncasecmp(v->value, "sig", 3))</span><br><span style="color: hsl(0, 100%, 40%);">- mode = MODE_SIGMA;</span><br><span style="color: hsl(0, 100%, 40%);">- else if (!strncasecmp(v->value, "im", 2))</span><br><span style="color: hsl(0, 100%, 40%);">- mode = MODE_IMMEDIATE;</span><br><span style="color: hsl(0, 100%, 40%);">- else if (!strncasecmp(v->value, "fxs", 3)) {</span><br><span style="color: hsl(0, 100%, 40%);">- mode = MODE_FXS;</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_cap_remove_by_type(prefcap, AST_MEDIA_TYPE_AUDIO); /* All non-voice */</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- else if (!strncasecmp(v->value, "fx", 2))</span><br><span style="color: hsl(0, 100%, 40%);">- mode = MODE_FXO;</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unknown mode: %s\n", v->value);</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!strcasecmp(v->name, "context")) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_copy_string(context, v->value, sizeof(context));</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!strcasecmp(v->name, "format")) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (!strcasecmp(v->value, "g729")) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_cap_remove_by_type(prefcap, AST_MEDIA_TYPE_UNKNOWN);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_cap_append(prefcap, ast_format_g729, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!strcasecmp(v->value, "g723.1")) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_cap_remove_by_type(prefcap, AST_MEDIA_TYPE_UNKNOWN);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_cap_append(prefcap, ast_format_g723, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!strcasecmp(v->value, "slinear")) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (mode == MODE_FXS) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_cap_append(prefcap, ast_format_slin, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_cap_remove_by_type(prefcap, AST_MEDIA_TYPE_UNKNOWN);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_cap_append(prefcap, ast_format_slin, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!strcasecmp(v->value, "ulaw")) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_cap_remove_by_type(prefcap, AST_MEDIA_TYPE_UNKNOWN);</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_cap_append(prefcap, ast_format_ulaw, 0);</span><br><span style="color: hsl(0, 100%, 40%);">- } else</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unknown format '%s'\n", v->value);</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!strcasecmp(v->name, "echocancel")) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (!strcasecmp(v->value, "off")) {</span><br><span style="color: hsl(0, 100%, 40%);">- echocancel = AEC_OFF;</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!strcasecmp(v->value, "low")) {</span><br><span style="color: hsl(0, 100%, 40%);">- echocancel = AEC_LOW;</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!strcasecmp(v->value, "medium")) {</span><br><span style="color: hsl(0, 100%, 40%);">- echocancel = AEC_MED;</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!strcasecmp(v->value, "high")) {</span><br><span style="color: hsl(0, 100%, 40%);">- echocancel = AEC_HIGH;</span><br><span style="color: hsl(0, 100%, 40%);">- } else</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_WARNING, "Unknown echo cancellation '%s'\n", v->value);</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!strcasecmp(v->name, "txgain")) {</span><br><span style="color: hsl(0, 100%, 40%);">- txgain = parse_gain_value(v->name, v->value);</span><br><span style="color: hsl(0, 100%, 40%);">- } else if (!strcasecmp(v->name, "rxgain")) {</span><br><span style="color: hsl(0, 100%, 40%);">- rxgain = parse_gain_value(v->name, v->value);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- v = v->next;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ast_mutex_unlock(&iflock);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (mode == MODE_FXS) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_format_cap_append_from_cap(phone_tech_fxs.capabilities, prefcap, AST_MEDIA_TYPE_UNKNOWN);</span><br><span style="color: hsl(0, 100%, 40%);">- cur_tech = &phone_tech_fxs;</span><br><span style="color: hsl(0, 100%, 40%);">- } else</span><br><span style="color: hsl(0, 100%, 40%);">- cur_tech = (struct ast_channel_tech *) &phone_tech;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Make sure we can register our Adtranphone channel type */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_channel_register(cur_tech)) {</span><br><span style="color: hsl(0, 100%, 40%);">- ast_log(LOG_ERROR, "Unable to register channel class 'Phone'\n");</span><br><span style="color: hsl(0, 100%, 40%);">- ast_config_destroy(cfg);</span><br><span style="color: hsl(0, 100%, 40%);">- __unload_module();</span><br><span style="color: hsl(0, 100%, 40%);">- return AST_MODULE_LOAD_DECLINE;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- ast_config_destroy(cfg);</span><br><span style="color: hsl(0, 100%, 40%);">- /* And start the monitor for the first time */</span><br><span style="color: hsl(0, 100%, 40%);">- restart_monitor();</span><br><span style="color: hsl(0, 100%, 40%);">- return AST_MODULE_LOAD_SUCCESS;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-AST_MODULE_INFO_STANDARD_DEPRECATED(ASTERISK_GPL_KEY, "Linux Telephony API Support");</span><br><span>diff --git a/configure b/configure</span><br><span>index 735a8e9..dfaa620 100755</span><br><span>--- a/configure</span><br><span>+++ b/configure</span><br><span>@@ -652,7 +652,6 @@</span><br><span> CONFIG_SDL</span><br><span> PBX_SO_NOSIGPIPE</span><br><span> PBX_MSG_NOSIGNAL</span><br><span style="color: hsl(0, 100%, 40%);">-PBX_IXJUSER</span><br><span> GMIME_LIBS</span><br><span> GMIME_CFLAGS</span><br><span> PORTAUDIO_LIBS</span><br><span>@@ -1296,7 +1295,6 @@</span><br><span> BUILD_VENDOR</span><br><span> BUILD_CPU</span><br><span> BUILD_PLATFORM</span><br><span style="color: hsl(0, 100%, 40%);">-astcachedir</span><br><span> astvarrundir</span><br><span> astlogdir</span><br><span> astspooldir</span><br><span>@@ -1309,6 +1307,7 @@</span><br><span> astlibdir</span><br><span> astheaderdir</span><br><span> astetcdir</span><br><span style="color: hsl(120, 100%, 40%);">+astcachedir</span><br><span> astsbindir</span><br><span> EGREP</span><br><span> GREP</span><br><span>@@ -1349,6 +1348,7 @@</span><br><span> docdir</span><br><span> oldincludedir</span><br><span> includedir</span><br><span style="color: hsl(120, 100%, 40%);">+runstatedir</span><br><span> localstatedir</span><br><span> sharedstatedir</span><br><span> sysconfdir</span><br><span>@@ -1538,6 +1538,7 @@</span><br><span> sysconfdir='${prefix}/etc'</span><br><span> sharedstatedir='${prefix}/com'</span><br><span> localstatedir='${prefix}/var'</span><br><span style="color: hsl(120, 100%, 40%);">+runstatedir='${localstatedir}/run'</span><br><span> includedir='${prefix}/include'</span><br><span> oldincludedir='/usr/include'</span><br><span> docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'</span><br><span>@@ -1790,6 +1791,15 @@</span><br><span> | -silent | --silent | --silen | --sile | --sil)</span><br><span> silent=yes ;;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ -runstatedir | --runstatedir | --runstatedi | --runstated \</span><br><span style="color: hsl(120, 100%, 40%);">+ | --runstate | --runstat | --runsta | --runst | --runs \</span><br><span style="color: hsl(120, 100%, 40%);">+ | --run | --ru | --r)</span><br><span style="color: hsl(120, 100%, 40%);">+ ac_prev=runstatedir ;;</span><br><span style="color: hsl(120, 100%, 40%);">+ -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \</span><br><span style="color: hsl(120, 100%, 40%);">+ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \</span><br><span style="color: hsl(120, 100%, 40%);">+ | --run=* | --ru=* | --r=*)</span><br><span style="color: hsl(120, 100%, 40%);">+ runstatedir=$ac_optarg ;;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)</span><br><span> ac_prev=sbindir ;;</span><br><span> -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \</span><br><span>@@ -1927,7 +1937,7 @@</span><br><span> for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \</span><br><span> datadir sysconfdir sharedstatedir localstatedir includedir \</span><br><span> oldincludedir docdir infodir htmldir dvidir pdfdir psdir \</span><br><span style="color: hsl(0, 100%, 40%);">- libdir localedir mandir</span><br><span style="color: hsl(120, 100%, 40%);">+ libdir localedir mandir runstatedir</span><br><span> do</span><br><span> eval ac_val=\$$ac_var</span><br><span> # Remove trailing slashes.</span><br><span>@@ -2080,6 +2090,7 @@</span><br><span> --sysconfdir=DIR read-only single-machine data [PREFIX/etc]</span><br><span> --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]</span><br><span> --localstatedir=DIR modifiable single-machine data [PREFIX/var]</span><br><span style="color: hsl(120, 100%, 40%);">+ --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]</span><br><span> --libdir=DIR object code libraries [EPREFIX/lib]</span><br><span> --includedir=DIR C header files [PREFIX/include]</span><br><span> --oldincludedir=DIR C header files for non-gcc [/usr/include]</span><br><span>@@ -10848,6 +10859,7 @@</span><br><span> </span><br><span> </span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> MISDN_DESCRIP="mISDN user"</span><br><span> MISDN_OPTION="misdn"</span><br><span> PBX_MISDN=0</span><br><span>@@ -14688,7 +14700,7 @@</span><br><span> We can't simply define LARGE_OFF_T to be 9223372036854775807,</span><br><span> since some C++ compilers masquerading as C compilers</span><br><span> incorrectly reject 9223372036854775807. */</span><br><span style="color: hsl(0, 100%, 40%);">-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))</span><br><span style="color: hsl(120, 100%, 40%);">+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))</span><br><span> int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721</span><br><span> && LARGE_OFF_T % 2147483647 == 1)</span><br><span> ? 1 : -1];</span><br><span>@@ -14734,7 +14746,7 @@</span><br><span> We can't simply define LARGE_OFF_T to be 9223372036854775807,</span><br><span> since some C++ compilers masquerading as C compilers</span><br><span> incorrectly reject 9223372036854775807. */</span><br><span style="color: hsl(0, 100%, 40%);">-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))</span><br><span style="color: hsl(120, 100%, 40%);">+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))</span><br><span> int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721</span><br><span> && LARGE_OFF_T % 2147483647 == 1)</span><br><span> ? 1 : -1];</span><br><span>@@ -14758,7 +14770,7 @@</span><br><span> We can't simply define LARGE_OFF_T to be 9223372036854775807,</span><br><span> since some C++ compilers masquerading as C compilers</span><br><span> incorrectly reject 9223372036854775807. */</span><br><span style="color: hsl(0, 100%, 40%);">-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))</span><br><span style="color: hsl(120, 100%, 40%);">+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))</span><br><span> int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721</span><br><span> && LARGE_OFF_T % 2147483647 == 1)</span><br><span> ? 1 : -1];</span><br><span>@@ -14803,7 +14815,7 @@</span><br><span> We can't simply define LARGE_OFF_T to be 9223372036854775807,</span><br><span> since some C++ compilers masquerading as C compilers</span><br><span> incorrectly reject 9223372036854775807. */</span><br><span style="color: hsl(0, 100%, 40%);">-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))</span><br><span style="color: hsl(120, 100%, 40%);">+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))</span><br><span> int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721</span><br><span> && LARGE_OFF_T % 2147483647 == 1)</span><br><span> ? 1 : -1];</span><br><span>@@ -14827,7 +14839,7 @@</span><br><span> We can't simply define LARGE_OFF_T to be 9223372036854775807,</span><br><span> since some C++ compilers masquerading as C compilers</span><br><span> incorrectly reject 9223372036854775807. */</span><br><span style="color: hsl(0, 100%, 40%);">-#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))</span><br><span style="color: hsl(120, 100%, 40%);">+#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))</span><br><span> int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721</span><br><span> && LARGE_OFF_T % 2147483647 == 1)</span><br><span> ? 1 : -1];</span><br><span>@@ -16127,6 +16139,8 @@</span><br><span> if (*(data + i) != *(data3 + i))</span><br><span> return 14;</span><br><span> close (fd);</span><br><span style="color: hsl(120, 100%, 40%);">+ free (data);</span><br><span style="color: hsl(120, 100%, 40%);">+ free (data3);</span><br><span> return 0;</span><br><span> }</span><br><span> _ACEOF</span><br><span>@@ -33458,22 +33472,6 @@</span><br><span> </span><br><span> </span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-ac_fn_c_check_header_compile "$LINENO" "linux/ixjuser.h" "ac_cv_header_linux_ixjuser_h" "</span><br><span style="color: hsl(0, 100%, 40%);">- #include <linux/version.h></span><br><span style="color: hsl(0, 100%, 40%);">- #ifdef HAVE_LINUX_COMPILER_H</span><br><span style="color: hsl(0, 100%, 40%);">- #include <linux/compiler.h></span><br><span style="color: hsl(0, 100%, 40%);">- #endif</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-"</span><br><span style="color: hsl(0, 100%, 40%);">-if test "x$ac_cv_header_linux_ixjuser_h" = xyes; then :</span><br><span style="color: hsl(0, 100%, 40%);">- PBX_IXJUSER=1</span><br><span style="color: hsl(0, 100%, 40%);">-else</span><br><span style="color: hsl(0, 100%, 40%);">- PBX_IXJUSER=0</span><br><span style="color: hsl(0, 100%, 40%);">-fi</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> # Used in res/res_pktccops</span><br><span> </span><br><span> if test "x${PBX_MSG_NOSIGNAL}" != "x1"; then</span><br><span>diff --git a/configure.ac b/configure.ac</span><br><span>index 2260fe6..ac5b41a 100644</span><br><span>--- a/configure.ac</span><br><span>+++ b/configure.ac</span><br><span>@@ -2803,14 +2803,6 @@</span><br><span> AC_CHECK_HEADER([linux/compiler.h],</span><br><span> [AC_DEFINE_UNQUOTED([HAVE_LINUX_COMPILER_H], 1, [Define to 1 if your system has linux/compiler.h.])])</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-AC_CHECK_HEADER([linux/ixjuser.h], [PBX_IXJUSER=1], [PBX_IXJUSER=0], [</span><br><span style="color: hsl(0, 100%, 40%);">- #include <linux/version.h></span><br><span style="color: hsl(0, 100%, 40%);">- #ifdef HAVE_LINUX_COMPILER_H</span><br><span style="color: hsl(0, 100%, 40%);">- #include <linux/compiler.h></span><br><span style="color: hsl(0, 100%, 40%);">- #endif</span><br><span style="color: hsl(0, 100%, 40%);">- ])</span><br><span style="color: hsl(0, 100%, 40%);">-AC_SUBST(PBX_IXJUSER)</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> # Used in res/res_pktccops</span><br><span> AST_C_DEFINE_CHECK([MSG_NOSIGNAL], [MSG_NOSIGNAL], [sys/socket.h])</span><br><span> AST_C_DEFINE_CHECK([SO_NOSIGPIPE], [SO_NOSIGPIPE], [sys/socket.h])</span><br><span>diff --git a/doc/UPGRADE-staging/chan_phone_removal.txt b/doc/UPGRADE-staging/chan_phone_removal.txt</span><br><span>new file mode 100644</span><br><span>index 0000000..76135be</span><br><span>--- /dev/null</span><br><span>+++ b/doc/UPGRADE-staging/chan_phone_removal.txt</span><br><span>@@ -0,0 +1,6 @@</span><br><span style="color: hsl(120, 100%, 40%);">+Subject: chan_phone</span><br><span style="color: hsl(120, 100%, 40%);">+Master-Only: True</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+This module was deprecated in Asterisk 16</span><br><span style="color: hsl(120, 100%, 40%);">+and is now being removed in accordance with</span><br><span style="color: hsl(120, 100%, 40%);">+the Asterisk Module Deprecation policy.</span><br><span>diff --git a/menuselect/configure b/menuselect/configure</span><br><span>index 1d15c1c..9986b4f 100755</span><br><span>--- a/menuselect/configure</span><br><span>+++ b/menuselect/configure</span><br><span>@@ -696,6 +696,7 @@</span><br><span> docdir</span><br><span> oldincludedir</span><br><span> includedir</span><br><span style="color: hsl(120, 100%, 40%);">+runstatedir</span><br><span> localstatedir</span><br><span> sharedstatedir</span><br><span> sysconfdir</span><br><span>@@ -777,6 +778,7 @@</span><br><span> sysconfdir='${prefix}/etc'</span><br><span> sharedstatedir='${prefix}/com'</span><br><span> localstatedir='${prefix}/var'</span><br><span style="color: hsl(120, 100%, 40%);">+runstatedir='${localstatedir}/run'</span><br><span> includedir='${prefix}/include'</span><br><span> oldincludedir='/usr/include'</span><br><span> docdir='${datarootdir}/doc/${PACKAGE}'</span><br><span>@@ -1029,6 +1031,15 @@</span><br><span> | -silent | --silent | --silen | --sile | --sil)</span><br><span> silent=yes ;;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ -runstatedir | --runstatedir | --runstatedi | --runstated \</span><br><span style="color: hsl(120, 100%, 40%);">+ | --runstate | --runstat | --runsta | --runst | --runs \</span><br><span style="color: hsl(120, 100%, 40%);">+ | --run | --ru | --r)</span><br><span style="color: hsl(120, 100%, 40%);">+ ac_prev=runstatedir ;;</span><br><span style="color: hsl(120, 100%, 40%);">+ -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \</span><br><span style="color: hsl(120, 100%, 40%);">+ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \</span><br><span style="color: hsl(120, 100%, 40%);">+ | --run=* | --ru=* | --r=*)</span><br><span style="color: hsl(120, 100%, 40%);">+ runstatedir=$ac_optarg ;;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)</span><br><span> ac_prev=sbindir ;;</span><br><span> -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \</span><br><span>@@ -1166,7 +1177,7 @@</span><br><span> for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \</span><br><span> datadir sysconfdir sharedstatedir localstatedir includedir \</span><br><span> oldincludedir docdir infodir htmldir dvidir pdfdir psdir \</span><br><span style="color: hsl(0, 100%, 40%);">- libdir localedir mandir</span><br><span style="color: hsl(120, 100%, 40%);">+ libdir localedir mandir runstatedir</span><br><span> do</span><br><span> eval ac_val=\$$ac_var</span><br><span> # Remove trailing slashes.</span><br><span>@@ -1319,6 +1330,7 @@</span><br><span> --sysconfdir=DIR read-only single-machine data [PREFIX/etc]</span><br><span> --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]</span><br><span> --localstatedir=DIR modifiable single-machine data [PREFIX/var]</span><br><span style="color: hsl(120, 100%, 40%);">+ --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]</span><br><span> --libdir=DIR object code libraries [EPREFIX/lib]</span><br><span> --includedir=DIR C header files [PREFIX/include]</span><br><span> --oldincludedir=DIR C header files for non-gcc [/usr/include]</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/16312">change 16312</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/16312"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I79a9961cb5062fadbccb0ea93f087bdd32685316 </div>
<div style="display:none"> Gerrit-Change-Number: 16312 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Joshua Colp <jcolp@sangoma.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>