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
|
||||
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 [ ! -f /usr/include/linux/if_wanpipe.h ] && echo " -DOLD_SANGOMA_API")
|
||||
SUBDIRS=channels pbx apps codecs formats
|
||||
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
|
||||
@@ -70,6 +71,7 @@ install: all
|
||||
rm -f /var/lib/asterisk/sounds/vm
|
||||
mkdir -p /var/spool/asterisk/vm
|
||||
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 . )
|
||||
@echo " +---- Asterisk Installation Complete -------+"
|
||||
@echo " + Asterisk has successfully been installed. +"
|
||||
@@ -92,7 +94,7 @@ samples: all datafiles
|
||||
for x in sounds/demo-*; do \
|
||||
install $$x /var/lib/asterisk/sounds; \
|
||||
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
|
||||
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 ; \
|
||||
|
@@ -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)
|
||||
|
||||
CFLAGS+=-Wno-missing-prototypes -Wno-missing-declarations
|
||||
|
||||
CFLAGS+=#-DVOFRDUMPER
|
||||
|
||||
all: $(CHANNEL_LIBS)
|
||||
|
@@ -28,9 +28,15 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <linux/if_packet.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 "adtranvofr.h"
|
||||
|
||||
/* #define VOFRDUMPER */
|
||||
|
||||
#define G723_MAX_BUF 2048
|
||||
|
||||
#define FR_API_MESS 16
|
||||
@@ -42,6 +48,8 @@ static char *config = "adtranvofr.conf";
|
||||
|
||||
static char context[AST_MAX_EXTENSION] = "default";
|
||||
|
||||
static char language[MAX_LANGUAGE] = "";
|
||||
|
||||
static int usecnt =0;
|
||||
static pthread_mutex_t usecnt_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
@@ -63,7 +71,11 @@ static int restart_monitor(void);
|
||||
|
||||
static struct vofr_pvt {
|
||||
int s; /* Raw socket for this DLCI */
|
||||
#ifdef OLD_SANGOMA_API
|
||||
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 */
|
||||
int outgoing; /* Does this channel support outgoing calls? */
|
||||
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 obuf[G723_MAX_BUF]; /* Output buffer */
|
||||
char context[AST_MAX_EXTENSION];
|
||||
char language[MAX_LANGUAGE];
|
||||
int ringgothangup; /* Have we received exactly one hangup after a ring */
|
||||
} *iflist = NULL;
|
||||
|
||||
#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)
|
||||
{
|
||||
int res;
|
||||
#ifdef OLD_SANGOMA_API
|
||||
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) {
|
||||
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;
|
||||
((struct vofr_pvt *)(ast->pvt->pvt))->owner = NULL;
|
||||
((struct vofr_pvt *)(ast->pvt->pvt))->ringgothangup = 0;
|
||||
pthread_mutex_lock(&usecnt_lock);
|
||||
usecnt--;
|
||||
if (usecnt < 0)
|
||||
@@ -465,6 +484,9 @@ static int vofr_answer(struct ast_channel *ast)
|
||||
cnt = ast_waitfor(ast, cnt);
|
||||
if (cnt > 0) {
|
||||
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;
|
||||
if (res < 0)
|
||||
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);
|
||||
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);
|
||||
#ifdef VOFRDUMPER
|
||||
vofr_dump_packet((void *)(vh), res);
|
||||
#endif
|
||||
ast->blocking = 0;
|
||||
res -= FR_API_MESS;
|
||||
if (res < sizeof(struct vofr_hdr *)) {
|
||||
@@ -552,15 +577,17 @@ static struct ast_frame *vofr_read(struct ast_channel *ast)
|
||||
switch(vh->data[0]) {
|
||||
case VOFR_SIGNAL_ON_HOOK:
|
||||
/* Hang up this line */
|
||||
if (ast->state == AST_STATE_UP)
|
||||
if ((ast->state == AST_STATE_UP) || (p->ringgothangup)) {
|
||||
return NULL;
|
||||
else {
|
||||
} else {
|
||||
fr->frametype = AST_FRAME_NULL;
|
||||
fr->subclass = 0;
|
||||
break;
|
||||
p->ringgothangup=1;
|
||||
}
|
||||
break;
|
||||
case VOFR_SIGNAL_RING:
|
||||
ast->rings++;
|
||||
p->ringgothangup = 0;
|
||||
break;
|
||||
case VOFR_SIGNAL_UNKNOWN:
|
||||
switch(vh->data[1]) {
|
||||
@@ -745,7 +772,11 @@ static struct ast_channel *vofr_new(struct vofr_pvt *i, int state)
|
||||
struct ast_channel *tmp;
|
||||
tmp = ast_channel_alloc();
|
||||
if (tmp) {
|
||||
#ifdef OLD_SANGOMA_API
|
||||
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->fd = i->s;
|
||||
/* 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->read = vofr_read;
|
||||
tmp->pvt->write = vofr_write;
|
||||
if (strlen(i->language))
|
||||
strncpy(tmp->language, i->language, sizeof(tmp->language));
|
||||
i->owner = tmp;
|
||||
pthread_mutex_lock(&usecnt_lock);
|
||||
usecnt++;
|
||||
@@ -788,9 +821,10 @@ static int vofr_mini_packet(struct vofr_pvt *i, struct vofr_hdr *pkt, int len)
|
||||
switch(pkt->data[0]) {
|
||||
case VOFR_SIGNAL_RING:
|
||||
/* 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);
|
||||
else
|
||||
} else
|
||||
ast_log(LOG_WARNING, "Got a ring, but there's an owner?\n");
|
||||
break;
|
||||
case VOFR_SIGNAL_OFF_HOOK:
|
||||
@@ -867,7 +901,11 @@ static void *do_monitor(void *data)
|
||||
i = iflist;
|
||||
while(i) {
|
||||
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);
|
||||
#else
|
||||
ast_log(LOG_WARNING, "Descriptor %d appears twice (%s)?\n", i->s, i->sa.sll_device);
|
||||
#endif
|
||||
if (!i->owner) {
|
||||
/* This needs to be watched, as it lacks an owner */
|
||||
FD_SET(i->s, &rfds);
|
||||
@@ -901,7 +939,11 @@ static void *do_monitor(void *data)
|
||||
while(i) {
|
||||
if (FD_ISSET(i->s, &rfds)) {
|
||||
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);
|
||||
#else
|
||||
ast_log(LOG_WARNING, "Whoa.... I'm owned but found (%d, %s)...\n", i->s, i->sa.sll_device);
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
res = read(i->s, i->buf, sizeof(i->buf));
|
||||
@@ -964,22 +1006,44 @@ static struct vofr_pvt *mkif(char *type, char *iface)
|
||||
if (tmp) {
|
||||
|
||||
/* Allocate a packet socket */
|
||||
#ifdef OLD_SANGOMA_API
|
||||
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) {
|
||||
ast_log(LOG_ERROR, "Unable to create socket: %s\n", strerror(errno));
|
||||
free(tmp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef OLD_SANGOMA_API
|
||||
/* Prepare sockaddr for binding */
|
||||
memset(&tmp->sa, 0, sizeof(tmp->sa));
|
||||
strncpy(tmp->sa.spkt_device, iface, sizeof(tmp->sa.spkt_device));
|
||||
tmp->sa.spkt_protocol = htons(0x16);
|
||||
tmp->sa.spkt_family = AF_PACKET;
|
||||
|
||||
/* Bind socket to specific interface */
|
||||
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,
|
||||
#else
|
||||
ast_log(LOG_ERROR, "Unable to bind to '%s': %s\n", tmp->sa.sll_device,
|
||||
#endif
|
||||
strerror(errno));
|
||||
free(tmp);
|
||||
return NULL;
|
||||
@@ -997,6 +1061,8 @@ static struct vofr_pvt *mkif(char *type, char *iface)
|
||||
tmp->dlcil = 0;
|
||||
tmp->dlcih = 0;
|
||||
tmp->cid = 1;
|
||||
tmp->ringgothangup = 0;
|
||||
strncpy(tmp->language, language, sizeof(tmp->language));
|
||||
strncpy(tmp->context, context, sizeof(tmp->context));
|
||||
/* User terminations are game for outgoing connections */
|
||||
if (!strcasecmp(type, "user"))
|
||||
@@ -1078,6 +1144,8 @@ int load_module()
|
||||
}
|
||||
} else if (!strcasecmp(v->name, "context")) {
|
||||
strncpy(context, v->value, sizeof(context));
|
||||
} else if (!strcasecmp(v->name, "language")) {
|
||||
strncpy(language, v->value, sizeof(language));
|
||||
}
|
||||
v = v->next;
|
||||
}
|
||||
|
Reference in New Issue
Block a user