Newer
Older
* Asterisk -- An open source telephony toolkit.
* Copyright (C) 1999 - 2005, Digium, Inc.
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2. See the LICENSE file
* at the top of the source tree.
*/
*
* \brief Implementation of Inter-Asterisk eXchange Protocol, v 2
*
* \author Mark Spencer <markster@digium.com>
/*** MODULEINFO
<support_level>core</support_level>
***/
Kevin P. Fleming
committed
#include "asterisk.h"
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include <sys/socket.h>
#include <netinet/in.h>
Kevin P. Fleming
committed
Kevin P. Fleming
committed
#include "asterisk/frame.h"
#include "asterisk/utils.h"
#include "asterisk/unaligned.h"
#include "asterisk/lock.h"
#include "iax2.h"
#include "iax2-parser.h"
static int frames = 0;
static int iframes = 0;
static int oframes = 0;
static void frame_cache_cleanup(void *data);
/*! \brief A per-thread cache of iax_frame structures */
Russell Bryant
committed
AST_THREADSTORAGE_CUSTOM(frame_cache, NULL, frame_cache_cleanup);
/*! \brief This is just so iax_frames, a list head struct for holding a list of
* iax_frame structures, is defined. */
AST_LIST_HEAD_NOLOCK(iax_frame_list, iax_frame);
struct iax_frames {
struct iax_frame_list list;
size_t size;
};
#define FRAME_CACHE_MAX_SIZE 20
static void internaloutput(const char *str)
{
}
static void internalerror(const char *str)
{
fprintf(stderr, "WARNING: %s", str);
}
static void (*outputf)(const char *str) = internaloutput;
static void (*errorf)(const char *str) = internalerror;
static void dump_addr(char *output, int maxlen, void *value, int len)
{
struct sockaddr_in sin;
Russell Bryant
committed
snprintf(output, maxlen, "IPV4 %s:%d", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
Russell Bryant
committed
ast_copy_string(output, "Invalid Address", maxlen);
static void dump_string_hex(char *output, int maxlen, void *value, int len)
{
int i = 0;
while (len-- && (i + 1) * 4 < maxlen) {
sprintf(output + (4 * i), "\\x%2.2x", *((unsigned char *)value + i));
i++;
}
}
static void dump_string(char *output, int maxlen, void *value, int len)
{
maxlen--;
if (maxlen > len)
maxlen = len;
Kevin P. Fleming
committed
strncpy(output, value, maxlen);
static void dump_prefs(char *output, int maxlen, void *value, int len)
{
struct ast_codec_pref pref;
int total_len = 0;
maxlen--;
total_len = maxlen;
if (maxlen > len)
maxlen = len;
Kevin P. Fleming
committed
strncpy(output, value, maxlen);
output[maxlen] = '\0';
ast_codec_pref_convert(&pref, output, total_len, 0);
memset(output,0,total_len);
ast_codec_pref_string(&pref, output, total_len);
}
static void dump_int(char *output, int maxlen, void *value, int len)
{
snprintf(output, maxlen, "%lu", (unsigned long)ntohl(get_unaligned_uint32(value)));
ast_copy_string(output, "Invalid INT", maxlen);
}
static void dump_short(char *output, int maxlen, void *value, int len)
{
if (len == (int)sizeof(unsigned short))
snprintf(output, maxlen, "%d", ntohs(get_unaligned_uint16(value)));
ast_copy_string(output, "Invalid SHORT", maxlen);
}
static void dump_byte(char *output, int maxlen, void *value, int len)
{
snprintf(output, maxlen, "%d", *((unsigned char *)value));
ast_copy_string(output, "Invalid BYTE", maxlen);
}
static void dump_datetime(char *output, int maxlen, void *value, int len)
{
Tilghman Lesher
committed
struct ast_tm tm;
unsigned long val = (unsigned long) ntohl(get_unaligned_uint32(value));
if (len == (int)sizeof(unsigned int)) {
tm.tm_sec = (val & 0x1f) << 1;
tm.tm_min = (val >> 5) & 0x3f;
tm.tm_hour = (val >> 11) & 0x1f;
tm.tm_mday = (val >> 16) & 0x1f;
tm.tm_mon = ((val >> 21) & 0x0f) - 1;
tm.tm_year = ((val >> 25) & 0x7f) + 100;
Tilghman Lesher
committed
ast_strftime(output, maxlen, "%Y-%m-%d %T", &tm);
} else
ast_copy_string(output, "Invalid DATETIME format!", maxlen);
static void dump_ipaddr(char *output, int maxlen, void *value, int len)
{
struct sockaddr_in sin;
if (len == (int)sizeof(unsigned int)) {
memcpy(&sin.sin_addr, value, len);
Russell Bryant
committed
snprintf(output, maxlen, "%s", ast_inet_ntoa(sin.sin_addr));
ast_copy_string(output, "Invalid IPADDR", maxlen);
}
static void dump_prov_flags(char *output, int maxlen, void *value, int len)
{
char buf[256] = "";
if (len == (int)sizeof(unsigned int))
snprintf(output, maxlen, "%lu (%s)", (unsigned long)ntohl(get_unaligned_uint32(value)),
iax_provflags2str(buf, sizeof(buf), ntohl(get_unaligned_uint32(value))));
ast_copy_string(output, "Invalid INT", maxlen);
static void dump_samprate(char *output, int maxlen, void *value, int len)
{
char tmp[256]="";
int sr;
if (len == (int)sizeof(unsigned short)) {
sr = ntohs(*((unsigned short *)value));
if (sr & IAX_RATE_8KHZ)
Loading
Loading full blame...