From 426381275d5ee3625029eaa4feece1e4aa345928 Mon Sep 17 00:00:00 2001 From: Mark Spencer Date: Thu, 6 Apr 2000 16:17:14 +0000 Subject: Version 0.1.3 from FTP git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@208 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/Makefile | 2 ++ channels/chan_vofr.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 77 insertions(+), 7 deletions(-) (limited to 'channels') diff --git a/channels/Makefile b/channels/Makefile index b0f14f4f1..411ce353d 100755 --- a/channels/Makefile +++ b/channels/Makefile @@ -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) diff --git a/channels/chan_vofr.c b/channels/chan_vofr.c index f8f171cd3..0ac36e081 100755 --- a/channels/chan_vofr.c +++ b/channels/chan_vofr.c @@ -28,9 +28,15 @@ #include #include #include +#ifndef OLD_SANGOMA_API +#include +#include +#endif #include #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; } -- cgit v1.2.3