mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-04 20:04:50 +00:00
Version 0.1.3 from FTP
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@208 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
4
Makefile
4
Makefile
@@ -25,6 +25,7 @@ DEBUG=-g #-pg
|
|||||||
INCLUDE=-Iinclude -I../include
|
INCLUDE=-Iinclude -I../include
|
||||||
CFLAGS=-pipe -Wall -Werror -Wmissing-prototypes -Wmissing-declarations -O6 $(DEBUG) $(INCLUDE) -D_REENTRANT
|
CFLAGS=-pipe -Wall -Werror -Wmissing-prototypes -Wmissing-declarations -O6 $(DEBUG) $(INCLUDE) -D_REENTRANT
|
||||||
CFLAGS+=$(shell if $(CC) -march=$(PROC) -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=$(PROC)"; fi)
|
CFLAGS+=$(shell if $(CC) -march=$(PROC) -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=$(PROC)"; fi)
|
||||||
|
CFLAGS+=$(shell [ ! -f /usr/include/linux/if_wanpipe.h ] && echo " -DOLD_SANGOMA_API")
|
||||||
SUBDIRS=channels pbx apps codecs formats
|
SUBDIRS=channels pbx apps codecs formats
|
||||||
LIBS=-ldl -lpthread -lreadline #-lefence
|
LIBS=-ldl -lpthread -lreadline #-lefence
|
||||||
OBJS=io.o sched.o logger.o frame.o loader.o config.o channel.o translate.o file.o say.o pbx.o cli.o md5.o asterisk.o
|
OBJS=io.o sched.o logger.o frame.o loader.o config.o channel.o translate.o file.o say.o pbx.o cli.o md5.o asterisk.o
|
||||||
@@ -70,6 +71,7 @@ install: all
|
|||||||
rm -f /var/lib/asterisk/sounds/vm
|
rm -f /var/lib/asterisk/sounds/vm
|
||||||
mkdir -p /var/spool/asterisk/vm
|
mkdir -p /var/spool/asterisk/vm
|
||||||
rm -f /usr/lib/asterisk/modules/chan_ixj.so
|
rm -f /usr/lib/asterisk/modules/chan_ixj.so
|
||||||
|
mkdir -p /var/lib/asterisk/sounds
|
||||||
( cd /var/lib/asterisk/sounds ; ln -s ../../../spool/asterisk/vm . )
|
( cd /var/lib/asterisk/sounds ; ln -s ../../../spool/asterisk/vm . )
|
||||||
@echo " +---- Asterisk Installation Complete -------+"
|
@echo " +---- Asterisk Installation Complete -------+"
|
||||||
@echo " + Asterisk has successfully been installed. +"
|
@echo " + Asterisk has successfully been installed. +"
|
||||||
@@ -92,7 +94,7 @@ samples: all datafiles
|
|||||||
for x in sounds/demo-*; do \
|
for x in sounds/demo-*; do \
|
||||||
install $$x /var/lib/asterisk/sounds; \
|
install $$x /var/lib/asterisk/sounds; \
|
||||||
done
|
done
|
||||||
mkdir -p /var/lib/asterisk/sounds/vm/1234
|
mkdir -p /var/spool/asterisk/vm/1234/INBOX
|
||||||
:> /var/lib/asterisk/sounds/vm/1234/unavail.gsm
|
:> /var/lib/asterisk/sounds/vm/1234/unavail.gsm
|
||||||
for x in vm-theperson digits/1 digits/2 digits/3 digits/4 vm-isunavail; do \
|
for x in vm-theperson digits/1 digits/2 digits/3 digits/4 vm-isunavail; do \
|
||||||
cat /var/lib/asterisk/sounds/$$x.gsm >> /var/lib/asterisk/sounds/vm/1234/unavail.gsm ; \
|
cat /var/lib/asterisk/sounds/$$x.gsm >> /var/lib/asterisk/sounds/vm/1234/unavail.gsm ; \
|
||||||
|
@@ -16,6 +16,8 @@ CHANNEL_LIBS=chan_vofr.so chan_modem.so \
|
|||||||
|
|
||||||
CHANNEL_LIBS+=$(shell [ -f /usr/include/linux/ixjuser.h ] && echo chan_phone.so)
|
CHANNEL_LIBS+=$(shell [ -f /usr/include/linux/ixjuser.h ] && echo chan_phone.so)
|
||||||
|
|
||||||
|
CFLAGS+=-Wno-missing-prototypes -Wno-missing-declarations
|
||||||
|
|
||||||
CFLAGS+=#-DVOFRDUMPER
|
CFLAGS+=#-DVOFRDUMPER
|
||||||
|
|
||||||
all: $(CHANNEL_LIBS)
|
all: $(CHANNEL_LIBS)
|
||||||
|
@@ -28,9 +28,15 @@
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <linux/if_packet.h>
|
#include <linux/if_packet.h>
|
||||||
#include <linux/if_ether.h>
|
#include <linux/if_ether.h>
|
||||||
|
#ifndef OLD_SANGOMA_API
|
||||||
|
#include <linux/if_wanpipe.h>
|
||||||
|
#include <linux/wanpipe.h>
|
||||||
|
#endif
|
||||||
#include <sys/signal.h>
|
#include <sys/signal.h>
|
||||||
#include "adtranvofr.h"
|
#include "adtranvofr.h"
|
||||||
|
|
||||||
|
/* #define VOFRDUMPER */
|
||||||
|
|
||||||
#define G723_MAX_BUF 2048
|
#define G723_MAX_BUF 2048
|
||||||
|
|
||||||
#define FR_API_MESS 16
|
#define FR_API_MESS 16
|
||||||
@@ -42,6 +48,8 @@ static char *config = "adtranvofr.conf";
|
|||||||
|
|
||||||
static char context[AST_MAX_EXTENSION] = "default";
|
static char context[AST_MAX_EXTENSION] = "default";
|
||||||
|
|
||||||
|
static char language[MAX_LANGUAGE] = "";
|
||||||
|
|
||||||
static int usecnt =0;
|
static int usecnt =0;
|
||||||
static pthread_mutex_t usecnt_lock = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t usecnt_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
@@ -63,7 +71,11 @@ static int restart_monitor(void);
|
|||||||
|
|
||||||
static struct vofr_pvt {
|
static struct vofr_pvt {
|
||||||
int s; /* Raw socket for this DLCI */
|
int s; /* Raw socket for this DLCI */
|
||||||
|
#ifdef OLD_SANGOMA_API
|
||||||
struct sockaddr_pkt sa; /* Sockaddr needed for sending, also has iface name */
|
struct sockaddr_pkt sa; /* Sockaddr needed for sending, also has iface name */
|
||||||
|
#else
|
||||||
|
struct wan_sockaddr_ll sa; /* Wanpipe sockaddr */
|
||||||
|
#endif
|
||||||
struct ast_channel *owner; /* Channel we belong to, possibly NULL */
|
struct ast_channel *owner; /* Channel we belong to, possibly NULL */
|
||||||
int outgoing; /* Does this channel support outgoing calls? */
|
int outgoing; /* Does this channel support outgoing calls? */
|
||||||
struct vofr_pvt *next; /* Next channel in list */
|
struct vofr_pvt *next; /* Next channel in list */
|
||||||
@@ -75,6 +87,8 @@ static struct vofr_pvt {
|
|||||||
char buf[G723_MAX_BUF]; /* Static buffer for reading frames */
|
char buf[G723_MAX_BUF]; /* Static buffer for reading frames */
|
||||||
char obuf[G723_MAX_BUF]; /* Output buffer */
|
char obuf[G723_MAX_BUF]; /* Output buffer */
|
||||||
char context[AST_MAX_EXTENSION];
|
char context[AST_MAX_EXTENSION];
|
||||||
|
char language[MAX_LANGUAGE];
|
||||||
|
int ringgothangup; /* Have we received exactly one hangup after a ring */
|
||||||
} *iflist = NULL;
|
} *iflist = NULL;
|
||||||
|
|
||||||
#ifdef VOFRDUMPER
|
#ifdef VOFRDUMPER
|
||||||
@@ -241,7 +255,11 @@ static void vofr_dump_packet(struct vofr_hdr *vh, int len)
|
|||||||
static int vofr_xmit(struct vofr_pvt *p, char *data, int len)
|
static int vofr_xmit(struct vofr_pvt *p, char *data, int len)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
#ifdef OLD_SANGOMA_API
|
||||||
res=sendto(p->s, data, len, 0, (struct sockaddr *)&p->sa, sizeof(struct sockaddr_pkt));
|
res=sendto(p->s, data, len, 0, (struct sockaddr *)&p->sa, sizeof(struct sockaddr_pkt));
|
||||||
|
#else
|
||||||
|
res=sendto(p->s, data, len, 0, (struct sockaddr *)&p->sa, sizeof(struct wan_sockaddr_ll));
|
||||||
|
#endif
|
||||||
if (res != len) {
|
if (res != len) {
|
||||||
ast_log(LOG_WARNING, "vofr_xmit returned %d\n", res);
|
ast_log(LOG_WARNING, "vofr_xmit returned %d\n", res);
|
||||||
}
|
}
|
||||||
@@ -434,6 +452,7 @@ static int vofr_hangup(struct ast_channel *ast)
|
|||||||
}
|
}
|
||||||
ast->state = AST_STATE_DOWN;
|
ast->state = AST_STATE_DOWN;
|
||||||
((struct vofr_pvt *)(ast->pvt->pvt))->owner = NULL;
|
((struct vofr_pvt *)(ast->pvt->pvt))->owner = NULL;
|
||||||
|
((struct vofr_pvt *)(ast->pvt->pvt))->ringgothangup = 0;
|
||||||
pthread_mutex_lock(&usecnt_lock);
|
pthread_mutex_lock(&usecnt_lock);
|
||||||
usecnt--;
|
usecnt--;
|
||||||
if (usecnt < 0)
|
if (usecnt < 0)
|
||||||
@@ -465,6 +484,9 @@ static int vofr_answer(struct ast_channel *ast)
|
|||||||
cnt = ast_waitfor(ast, cnt);
|
cnt = ast_waitfor(ast, cnt);
|
||||||
if (cnt > 0) {
|
if (cnt > 0) {
|
||||||
res = read(ast->fd, buf, sizeof(buf));
|
res = read(ast->fd, buf, sizeof(buf));
|
||||||
|
#ifdef VOFRDUMPER
|
||||||
|
vofr_dump_packet((void *)(buf +FR_API_MESS), res - FR_API_MESS);
|
||||||
|
#endif
|
||||||
res -= FR_API_MESS;
|
res -= FR_API_MESS;
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
ast_log(LOG_WARNING, "Warning: read failed (%s) on %s\n", strerror(errno), ast->name);
|
ast_log(LOG_WARNING, "Warning: read failed (%s) on %s\n", strerror(errno), ast->name);
|
||||||
@@ -531,6 +553,9 @@ static struct ast_frame *vofr_read(struct ast_channel *ast)
|
|||||||
CHECK_BLOCKING(ast);
|
CHECK_BLOCKING(ast);
|
||||||
res = read(p->s, ((char *)vh) - FR_API_MESS,
|
res = read(p->s, ((char *)vh) - FR_API_MESS,
|
||||||
G723_MAX_BUF - AST_FRIENDLY_OFFSET - sizeof(struct ast_frame) + sizeof(struct vofr_hdr) + FR_API_MESS);
|
G723_MAX_BUF - AST_FRIENDLY_OFFSET - sizeof(struct ast_frame) + sizeof(struct vofr_hdr) + FR_API_MESS);
|
||||||
|
#ifdef VOFRDUMPER
|
||||||
|
vofr_dump_packet((void *)(vh), res);
|
||||||
|
#endif
|
||||||
ast->blocking = 0;
|
ast->blocking = 0;
|
||||||
res -= FR_API_MESS;
|
res -= FR_API_MESS;
|
||||||
if (res < sizeof(struct vofr_hdr *)) {
|
if (res < sizeof(struct vofr_hdr *)) {
|
||||||
@@ -552,15 +577,17 @@ static struct ast_frame *vofr_read(struct ast_channel *ast)
|
|||||||
switch(vh->data[0]) {
|
switch(vh->data[0]) {
|
||||||
case VOFR_SIGNAL_ON_HOOK:
|
case VOFR_SIGNAL_ON_HOOK:
|
||||||
/* Hang up this line */
|
/* Hang up this line */
|
||||||
if (ast->state == AST_STATE_UP)
|
if ((ast->state == AST_STATE_UP) || (p->ringgothangup)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
else {
|
} else {
|
||||||
fr->frametype = AST_FRAME_NULL;
|
fr->frametype = AST_FRAME_NULL;
|
||||||
fr->subclass = 0;
|
fr->subclass = 0;
|
||||||
break;
|
p->ringgothangup=1;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
case VOFR_SIGNAL_RING:
|
case VOFR_SIGNAL_RING:
|
||||||
ast->rings++;
|
ast->rings++;
|
||||||
|
p->ringgothangup = 0;
|
||||||
break;
|
break;
|
||||||
case VOFR_SIGNAL_UNKNOWN:
|
case VOFR_SIGNAL_UNKNOWN:
|
||||||
switch(vh->data[1]) {
|
switch(vh->data[1]) {
|
||||||
@@ -745,7 +772,11 @@ static struct ast_channel *vofr_new(struct vofr_pvt *i, int state)
|
|||||||
struct ast_channel *tmp;
|
struct ast_channel *tmp;
|
||||||
tmp = ast_channel_alloc();
|
tmp = ast_channel_alloc();
|
||||||
if (tmp) {
|
if (tmp) {
|
||||||
|
#ifdef OLD_SANGOMA_API
|
||||||
snprintf(tmp->name, sizeof(tmp->name), "AdtranVoFR/%s", i->sa.spkt_device);
|
snprintf(tmp->name, sizeof(tmp->name), "AdtranVoFR/%s", i->sa.spkt_device);
|
||||||
|
#else
|
||||||
|
snprintf(tmp->name, sizeof(tmp->name), "AdtranVoFR/%s", i->sa.sll_device);
|
||||||
|
#endif
|
||||||
tmp->type = type;
|
tmp->type = type;
|
||||||
tmp->fd = i->s;
|
tmp->fd = i->s;
|
||||||
/* Adtran VoFR supports only G723.1 format data. G711 (ulaw) would be nice too */
|
/* Adtran VoFR supports only G723.1 format data. G711 (ulaw) would be nice too */
|
||||||
@@ -760,6 +791,8 @@ static struct ast_channel *vofr_new(struct vofr_pvt *i, int state)
|
|||||||
tmp->pvt->answer = vofr_answer;
|
tmp->pvt->answer = vofr_answer;
|
||||||
tmp->pvt->read = vofr_read;
|
tmp->pvt->read = vofr_read;
|
||||||
tmp->pvt->write = vofr_write;
|
tmp->pvt->write = vofr_write;
|
||||||
|
if (strlen(i->language))
|
||||||
|
strncpy(tmp->language, i->language, sizeof(tmp->language));
|
||||||
i->owner = tmp;
|
i->owner = tmp;
|
||||||
pthread_mutex_lock(&usecnt_lock);
|
pthread_mutex_lock(&usecnt_lock);
|
||||||
usecnt++;
|
usecnt++;
|
||||||
@@ -788,9 +821,10 @@ static int vofr_mini_packet(struct vofr_pvt *i, struct vofr_hdr *pkt, int len)
|
|||||||
switch(pkt->data[0]) {
|
switch(pkt->data[0]) {
|
||||||
case VOFR_SIGNAL_RING:
|
case VOFR_SIGNAL_RING:
|
||||||
/* If we get a RING, we definitely want to start a new thread */
|
/* If we get a RING, we definitely want to start a new thread */
|
||||||
if (!i->owner)
|
if (!i->owner) {
|
||||||
|
i->ringgothangup = 0;
|
||||||
vofr_new(i, AST_STATE_RING);
|
vofr_new(i, AST_STATE_RING);
|
||||||
else
|
} else
|
||||||
ast_log(LOG_WARNING, "Got a ring, but there's an owner?\n");
|
ast_log(LOG_WARNING, "Got a ring, but there's an owner?\n");
|
||||||
break;
|
break;
|
||||||
case VOFR_SIGNAL_OFF_HOOK:
|
case VOFR_SIGNAL_OFF_HOOK:
|
||||||
@@ -867,7 +901,11 @@ static void *do_monitor(void *data)
|
|||||||
i = iflist;
|
i = iflist;
|
||||||
while(i) {
|
while(i) {
|
||||||
if (FD_ISSET(i->s, &rfds))
|
if (FD_ISSET(i->s, &rfds))
|
||||||
|
#ifdef OLD_SANGOMA_API
|
||||||
ast_log(LOG_WARNING, "Descriptor %d appears twice (%s)?\n", i->s, i->sa.spkt_device);
|
ast_log(LOG_WARNING, "Descriptor %d appears twice (%s)?\n", i->s, i->sa.spkt_device);
|
||||||
|
#else
|
||||||
|
ast_log(LOG_WARNING, "Descriptor %d appears twice (%s)?\n", i->s, i->sa.sll_device);
|
||||||
|
#endif
|
||||||
if (!i->owner) {
|
if (!i->owner) {
|
||||||
/* This needs to be watched, as it lacks an owner */
|
/* This needs to be watched, as it lacks an owner */
|
||||||
FD_SET(i->s, &rfds);
|
FD_SET(i->s, &rfds);
|
||||||
@@ -901,7 +939,11 @@ static void *do_monitor(void *data)
|
|||||||
while(i) {
|
while(i) {
|
||||||
if (FD_ISSET(i->s, &rfds)) {
|
if (FD_ISSET(i->s, &rfds)) {
|
||||||
if (i->owner) {
|
if (i->owner) {
|
||||||
|
#ifdef OLD_SANGOMA_API
|
||||||
ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d, %s)...\n", i->s, i->sa.spkt_device);
|
ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d, %s)...\n", i->s, i->sa.spkt_device);
|
||||||
|
#else
|
||||||
|
ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d, %s)...\n", i->s, i->sa.sll_device);
|
||||||
|
#endif
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
res = read(i->s, i->buf, sizeof(i->buf));
|
res = read(i->s, i->buf, sizeof(i->buf));
|
||||||
@@ -964,22 +1006,44 @@ static struct vofr_pvt *mkif(char *type, char *iface)
|
|||||||
if (tmp) {
|
if (tmp) {
|
||||||
|
|
||||||
/* Allocate a packet socket */
|
/* Allocate a packet socket */
|
||||||
|
#ifdef OLD_SANGOMA_API
|
||||||
tmp->s = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL));
|
tmp->s = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL));
|
||||||
|
#else
|
||||||
|
/* Why the HELL does Sangoma change their API every damn time
|
||||||
|
they make a new driver release?!?!?! Leave it the hell
|
||||||
|
alone this time. */
|
||||||
|
tmp->s = socket(AF_WANPIPE, SOCK_RAW, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (tmp->s < 0) {
|
if (tmp->s < 0) {
|
||||||
ast_log(LOG_ERROR, "Unable to create socket: %s\n", strerror(errno));
|
ast_log(LOG_ERROR, "Unable to create socket: %s\n", strerror(errno));
|
||||||
free(tmp);
|
free(tmp);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef OLD_SANGOMA_API
|
||||||
/* Prepare sockaddr for binding */
|
/* Prepare sockaddr for binding */
|
||||||
memset(&tmp->sa, 0, sizeof(tmp->sa));
|
memset(&tmp->sa, 0, sizeof(tmp->sa));
|
||||||
strncpy(tmp->sa.spkt_device, iface, sizeof(tmp->sa.spkt_device));
|
strncpy(tmp->sa.spkt_device, iface, sizeof(tmp->sa.spkt_device));
|
||||||
tmp->sa.spkt_protocol = htons(0x16);
|
tmp->sa.spkt_protocol = htons(0x16);
|
||||||
tmp->sa.spkt_family = AF_PACKET;
|
tmp->sa.spkt_family = AF_PACKET;
|
||||||
|
|
||||||
/* Bind socket to specific interface */
|
|
||||||
if (bind(tmp->s, (struct sockaddr *)&tmp->sa, sizeof(struct sockaddr))) {
|
if (bind(tmp->s, (struct sockaddr *)&tmp->sa, sizeof(struct sockaddr))) {
|
||||||
|
#else
|
||||||
|
/* Prepare sockaddr for binding */
|
||||||
|
memset(&tmp->sa, 0, sizeof(tmp->sa));
|
||||||
|
tmp->sa.sll_family = AF_WANPIPE;
|
||||||
|
tmp->sa.sll_protocol = htons(ETH_P_IP);
|
||||||
|
strncpy(tmp->sa.sll_device, iface, sizeof(tmp->sa.sll_device));
|
||||||
|
strncpy(tmp->sa.sll_card, "wanpipe1", sizeof(tmp->sa.sll_card));
|
||||||
|
tmp->sa.sll_ifindex = 0;
|
||||||
|
if (bind(tmp->s, (struct sockaddr *)&tmp->sa, sizeof(struct wan_sockaddr_ll))) {
|
||||||
|
#endif
|
||||||
|
/* Bind socket to specific interface */
|
||||||
|
#ifdef OLD_SANGOMA_API
|
||||||
ast_log(LOG_ERROR, "Unable to bind to '%s': %s\n", tmp->sa.spkt_device,
|
ast_log(LOG_ERROR, "Unable to bind to '%s': %s\n", tmp->sa.spkt_device,
|
||||||
|
#else
|
||||||
|
ast_log(LOG_ERROR, "Unable to bind to '%s': %s\n", tmp->sa.sll_device,
|
||||||
|
#endif
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
free(tmp);
|
free(tmp);
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -997,6 +1061,8 @@ static struct vofr_pvt *mkif(char *type, char *iface)
|
|||||||
tmp->dlcil = 0;
|
tmp->dlcil = 0;
|
||||||
tmp->dlcih = 0;
|
tmp->dlcih = 0;
|
||||||
tmp->cid = 1;
|
tmp->cid = 1;
|
||||||
|
tmp->ringgothangup = 0;
|
||||||
|
strncpy(tmp->language, language, sizeof(tmp->language));
|
||||||
strncpy(tmp->context, context, sizeof(tmp->context));
|
strncpy(tmp->context, context, sizeof(tmp->context));
|
||||||
/* User terminations are game for outgoing connections */
|
/* User terminations are game for outgoing connections */
|
||||||
if (!strcasecmp(type, "user"))
|
if (!strcasecmp(type, "user"))
|
||||||
@@ -1078,6 +1144,8 @@ int load_module()
|
|||||||
}
|
}
|
||||||
} else if (!strcasecmp(v->name, "context")) {
|
} else if (!strcasecmp(v->name, "context")) {
|
||||||
strncpy(context, v->value, sizeof(context));
|
strncpy(context, v->value, sizeof(context));
|
||||||
|
} else if (!strcasecmp(v->name, "language")) {
|
||||||
|
strncpy(language, v->value, sizeof(language));
|
||||||
}
|
}
|
||||||
v = v->next;
|
v = v->next;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user