# @echo Please report any bug. To compile use \"make beta\".
# @exit
-all: $(LCR) $(LCRADMIN) $(CHAN_LCR) $(GEN) $(GENW) $(GENRC) $(GENEXT)
- @sh -c 'grep -n strcpy *.c* ; if test $$''? = 0 ; then echo "dont use strcpy, use makro instead." ; exit -1 ; fi'
- @sh -c 'grep -n strncpy *.c* ; if test $$''? = 0 ; then echo "dont use strncpy, use makro instead." ; exit -1 ; fi'
- @sh -c 'grep -n strcat *.c* ; if test $$''? = 0 ; then echo "dont use strcat, use makro instead." ; exit -1 ; fi'
- @sh -c 'grep -n strncat *.c* ; if test $$''? = 0 ; then echo "dont use strncat, use makro instead." ; exit -1 ; fi'
- @sh -c 'grep -n sprintf *.c* ; if test $$''? = 0 ; then echo "dont use sprintf, use makro instead." ; exit -1 ; fi'
- @sh -c 'grep -n snprintf *.c* ; if test $$''? = 0 ; then echo "dont use snprintf, use makro instead." ; exit -1 ; fi'
+all: $(CHAN_LCR) $(LCR) $(LCRADMIN) $(GEN) $(GENW) $(GENRC) $(GENEXT)
+ @sh -c 'grep -n strcpy *.c* --exclude chan_lcr.c --exclude bchannel.c ; if test $$''? = 0 ; then echo "dont use strcpy, use makro instead." ; exit -1 ; fi'
+ @sh -c 'grep -n strncpy *.c* --exclude chan_lcr.c --exclude bchannel.c ; if test $$''? = 0 ; then echo "dont use strncpy, use makro instead." ; exit -1 ; fi'
+ @sh -c 'grep -n strcat *.c* --exclude chan_lcr.c --exclude bchannel.c ; if test $$''? = 0 ; then echo "dont use strcat, use makro instead." ; exit -1 ; fi'
+ @sh -c 'grep -n strncat *.c* --exclude chan_lcr.c --exclude bchannel.c ; if test $$''? = 0 ; then echo "dont use strncat, use makro instead." ; exit -1 ; fi'
+ @sh -c 'grep -n sprintf *.c* --exclude chan_lcr.c --exclude bchannel.c ; if test $$''? = 0 ; then echo "dont use sprintf, use makro instead." ; exit -1 ; fi'
+ @sh -c 'grep -n snprintf *.c* --exclude chan_lcr.c --exclude bchannel.c ; if test $$''? = 0 ; then echo "dont use snprintf, use makro instead." ; exit -1 ; fi'
@echo "All LCR binaries done"
@sync
@exit
trace.o: trace.c *.h Makefile
$(CC) -c $(CFLAGS) trace.c -o trace.o
+chan_lcr.o: chan_lcr.c *.h Makefile
+ $(CC) -c $(CFLAGS) chan_lcr.c -o chan_lcr.o
+
+bchannel.o: bchannel.c *.h Makefile
+ $(CC) -c $(CFLAGS) bchannel.c -o bchannel.o
+
#$(WIZZARD): wizzard.c Makefile
# $(CC) $(LIBDIR) $(CFLAGS) -lm wizzard.c \
$(CC) $(LIBDIR) $(CFLAGS) $(CURSES) -lm admin_client.c cause.c \
-o $(LCRADMIN)
-$(CHAN_LCR): asterisk_client.c *.h Makefile
- $(CC) $(LIBDIR) $(CFLAGS) $(CURSES) -lm asterisk_client.c \
- -o $(CHAN_LCR)
+$(CHAN_LCR): chan_lcr.o bchannel.o
+ $(CD) $(LIBDIR) chan_lcr.o bchannel.o \
+ $(LIBS) -o $(CHAN_LCR)
$(LCRWATCH): watch.c *.h Makefile
$(CC) $(LIBDIR) $(CFLAGS) -lm watch.c \
Changes in Version 2.5
- Fixed callback bug. (International numbers were not detected.)
-- Fixed typos (mostly "incomming") - thanx Lars.
+- Fixed typos (mostly "incoming") - thanx Lars.
- Fixed vbox-email bug - thanx Martin. (and also the compiler error)
- Fixed compiler bug, that caused compiling without crypto lib to fail.
- Fixed some mISDN crash problems.
Changes in Version 2.7
- Fixed lots of bugs.
- Now receive stream from mISDN is disabled when not needed.
-- Added NT mode support for incomming "SETUP_ACKNOWLEDGE".
+- Added NT mode support for incoming "SETUP_ACKNOWLEDGE".
Changes in Version 3.0
- Advanced routing capability to replace the numbering_*.conf
- Fixed minor audio gain bug.
- Moved timeout setting from extension to interface.conf.
-Changes in Version 0.3
+Changes in Version 0.4
- Complete set of EFI samples
+Changes in Version 0.5
+- Preperations for Asterisk channel driver (chan_lcr)
if (e_state!=EPOINT_STATE_IN_SETUP
&& e_state!=EPOINT_STATE_IN_OVERLAP)
{
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d): we are not in incomming setup/overlap state, so we ignore init/dialing process.\n", ea_endpoint->ep_serial, e_rule_nesting);
+ PDEBUG(DEBUG_EPOINT, "EPOINT(%d): we are not in incoming setup/overlap state, so we ignore init/dialing process.\n", ea_endpoint->ep_serial, e_rule_nesting);
e_match_timeout = 0;
goto end;
}
if (e_state!=EPOINT_STATE_IN_SETUP
&& e_state!=EPOINT_STATE_IN_OVERLAP)
{
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d): AFTER init process: we are not in incomming setup/overlap state anymore, so we ignore further dialing process.\n", ea_endpoint->ep_serial, e_rule_nesting);
+ PDEBUG(DEBUG_EPOINT, "EPOINT(%d): AFTER init process: we are not in incoming setup/overlap state anymore, so we ignore further dialing process.\n", ea_endpoint->ep_serial, e_rule_nesting);
goto display_action;
}
}
write_log(e_ext.number, callertext, dialingtext, e_start, e_stop, 0, cause, location);
/* store last received call for reply-list */
- if (e_origin == 1) // outgoing to phone is incomming for user
+ if (e_origin == 1) // outgoing to phone is incoming for user
if (e_callerinfo.id[0] || e_callerinfo.extension[0])
if (e_ext.anon_ignore || e_callerinfo.present!=INFO_PRESENT_RESTRICTED)
{
}
/* store last made call for reply-list */
- if (e_origin == 0) // incomming from phone is outgoing for user
+ if (e_origin == 0) // incoming from phone is outgoing for user
if (e_dialinginfo.id[0])
{
if (!!strcmp(e_dialinginfo.id, e_ext.last_out[0]))
if (sock < 0)
return(0);
- /* check for new incomming connections */
+ /* check for new incoming connections */
if ((new_sock = accept(sock, (struct sockaddr *)&sock_address, &sock_len)) >= 0)
{
work = 1;
if (ioctl(new_sock, FIONBIO, (unsigned char *)(&on)) >= 0)
{
//#warning
-// PERROR("DEBUG incomming socket %d, serial=%d\n", new_sock, sockserial);
+// PERROR("DEBUG incoming socket %d, serial=%d\n", new_sock, sockserial);
memuse++;
fhuse++;
admin->sockserial = sockserial++;
memset(&e_ext, 0, sizeof(struct extension));
// *************** NOTE: also change value in read_extension() **************
e_ext.rights = 4; /* international */
- e_ext.rxvol = e_ext.txvol = 0;
+ e_ext.rx_gain = e_ext.tx_gain = 0;
e_state = EPOINT_STATE_IDLE;
e_ext.number[0] = '\0';
e_extension_interface[0] = '\0';
/* set volume of rx and tx */
if (param->setup.callerinfo.itype == INFO_ITYPE_ISDN_EXTENSION)
- if (e_ext.txvol!=0 || e_ext.rxvol!=0)
+ if (e_ext.tx_gain!=0 || e_ext.rx_gain!=0)
{
message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_mISDNSIGNAL);
message->param.mISDNsignal.message = mISDNSIGNAL_VOLUME;
- message->param.mISDNsignal.rxvol = e_ext.txvol;
- message->param.mISDNsignal.txvol = e_ext.rxvol;
+ message->param.mISDNsignal.rx_gain = e_ext.tx_gain;
+ message->param.mISDNsignal.tx_gain = e_ext.rx_gain;
message_put(message);
}
new_state(EPOINT_STATE_CONNECT);
/* set volume of rx and tx */
- if (e_ext.txvol!=0 || e_ext.rxvol!=0)
+ if (e_ext.tx_gain!=0 || e_ext.rx_gain!=0)
{
message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_mISDNSIGNAL);
message->param.mISDNsignal.message = mISDNSIGNAL_VOLUME;
- message->param.mISDNsignal.rxvol = e_ext.txvol;
- message->param.mISDNsignal.txvol = e_ext.rxvol;
+ message->param.mISDNsignal.rx_gain = e_ext.tx_gain;
+ message->param.mISDNsignal.tx_gain = e_ext.rx_gain;
message_put(message);
}
case INFO_NOTIFY_USER_RESUMED:
/* set volume of rx and tx */
if (param->setup.callerinfo.itype == INFO_ITYPE_ISDN_EXTENSION)
- if (e_ext.txvol!=0 || e_ext.rxvol!=0)
+ if (e_ext.tx_gain!=0 || e_ext.rx_gain!=0)
if (portlist)
{
message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_mISDNSIGNAL);
message->param.mISDNsignal.message = mISDNSIGNAL_VOLUME;
- message->param.mISDNsignal.rxvol = e_ext.txvol;
- message->param.mISDNsignal.txvol = e_ext.rxvol;
+ message->param.mISDNsignal.rx_gain = e_ext.tx_gain;
+ message->param.mISDNsignal.tx_gain = e_ext.rx_gain;
message_put(message);
}
/* set current tone */
struct redir_info e_redirinfo; /* info on redirection (to the calling user) */
struct capa_info e_capainfo; /* info on l3,l2 capacity */
time_t e_start, e_stop; /* time */
- int e_origin; /* origin of call 0=incomming 1=outgoing */
+ int e_origin; /* origin of call 0=incoming 1=outgoing */
struct route_ruleset *e_ruleset; /* current ruleset pointer (NULL=no ruleset) */
struct route_rule *e_rule; /* current rule pointer (NULL=no rule) */
struct route_action *e_action; /* current action pointer (NULL=no action) */
--- /dev/null
+/*****************************************************************************\
+** **
+** Linux Call Router **
+** **
+**---------------------------------------------------------------------------**
+** Copyright: Andreas Eversberg **
+** **
+** mISDN channel handlin for remote application **
+** **
+\*****************************************************************************/
+
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <poll.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef SOCKET_MISDN
+#include <netinet/udp.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <pthread.h>
+#else
+#include "mISDNlib.h"
+#include <linux/mISDNif.h>
+#endif
+#include "bchannel.h"
+
+#ifndef ISDN_PID_L4_B_USER
+#define ISDN_PID_L4_B_USER 0x440000ff
+#endif
+
+#define PERROR(arg...) fprintf(stderr, ##arg)
+#define PDEBUG(arg...) while(0)
+
+pid_t bchannel_pid;
+
+enum {
+ BSTATE_IDLE,
+ BSTATE_ACTIVATING,
+ BSTATE_ACTIVE,
+};
+
+#ifdef MISDN_SOCKET
+int bchannel_socket = -1;
+
+int bchannel_initialize(void)
+{
+ /* try to open raw socket to check kernel */
+ bchannel_socket = socket(PF_ISDN, SOCK_RAW, ISDN_P_BASE);
+ if (bchannel_socket < 0)
+ {
+ PERROR("Cannot open mISDN due to %s. (Does your Kernel support socket based mISDN?)\n", strerror(errno));
+ return(-1);
+ }
+
+ mISDN_debug_init(global_debug, NULL, NULL, NULL);
+
+ bchannel_pid = get_pid();
+
+ /* init mlayer3 */
+ init_layer3(4); // buffer of 4
+
+ return(0);
+}
+
+void bchannel_deinitialize(void)
+{
+ cleanup_layer3();
+
+ mISDN_debug_close();
+
+ if (bchannel_socket > -1)
+ close(bchannel_socket);
+}
+#else
+int bchannel_entity = 0; /* used for udevice */
+int bchannel_device = -1; /* the device handler and port list */
+
+int bchannel_initialize(void)
+{
+ char debug_log[128];
+ unsigned char buff[1025];
+ iframe_t *frm = (iframe_t *)buff;
+ int ret;
+
+ /* open mISDNdevice if not already open */
+ if (bchannel_device < 0)
+ {
+ ret = mISDN_open();
+ if (ret < 0)
+ {
+ PERROR("cannot open mISDN device ret=%d errno=%d (%s) Check for mISDN modules!\nAlso did you create \"/dev/mISDN\"? Do: \"mknod /dev/mISDN c 46 0\"\n", ret, errno, strerror(errno));
+ return(-1);
+ }
+ bchannel_device = ret;
+ PDEBUG("mISDN device opened.\n");
+
+ /* create entity for layer 3 TE-mode */
+ mISDN_write_frame(bchannel_device, buff, 0, MGR_NEWENTITY | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
+ ret = mISDN_read_frame(bchannel_device, frm, sizeof(iframe_t), 0, MGR_NEWENTITY | CONFIRM, TIMEOUT_1SEC);
+ if (ret < (int)mISDN_HEADER_LEN)
+ {
+ noentity:
+ PERROR("Cannot request MGR_NEWENTITY from mISDN. Exitting due to software bug.");
+ return(-1);
+ }
+ bchannel_entity = frm->dinfo & 0xffff;
+ if (!bchannel_entity)
+ goto noentity;
+ }
+ return(0);
+}
+
+void bchannel_deinitialize(void)
+{
+ unsigned char buff[1025];
+
+ if (bchannel_device >= 0)
+ {
+ /* free entity */
+ mISDN_write_frame(bchannel_device, buff, 0, MGR_DELENTITY | REQUEST, bchannel_entity, 0, NULL, TIMEOUT_1SEC);
+ /* close device */
+ mISDN_close(bchannel_device);
+ bchannel_device = -1;
+ }
+}
+#endif
+
+/*
+ * send control information to the channel (dsp-module)
+ */
+static void ph_control(unsigned long handle, unsigned long c1, unsigned long c2, char *trace_name, int trace_value)
+{
+#ifdef SOCKET_MISDN
+ unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
+ struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
+ unsigned long *d = buffer+MISDN_HEADER_LEN;
+ int ret;
+
+ ctrl->prim = PH_CONTROL_REQ;
+ ctrl->id = 0;
+ *d++ = c1;
+ *d++ = c2;
+ ret = sendto(handle, buffer, MISDN_HEADER_LEN+sizeof(int)*2, 0, NULL, 0);
+ if (!ret)
+ PERROR("Failed to send to socket %d\n", handle);
+#else
+ unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+sizeof(int)];
+ iframe_t *ctrl = (iframe_t *)buffer;
+ unsigned long *d = (unsigned long *)&ctrl->data.p;
+
+ ctrl->prim = PH_CONTROL | REQUEST;
+ ctrl->addr = handle | FLG_MSG_DOWN;
+ ctrl->dinfo = 0;
+ ctrl->len = sizeof(int)*2;
+ *d++ = c1;
+ *d++ = c2;
+ mISDN_write(bchannel_device, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
+#endif
+#if 0
+ chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
+ if (c1 == CMX_CONF_JOIN)
+ add_trace(trace_name, NULL, "0x%08x", trace_value);
+ else
+ add_trace(trace_name, NULL, "%d", trace_value);
+ end_trace();
+#endif
+}
+
+static void ph_control_block(unsigned long handle, unsigned long c1, void *c2, int c2_len, char *trace_name, int trace_value)
+{
+#ifdef SOCKET_MISDN
+ unsigned char buffer[MISDN_HEADER_LEN+sizeof(int)+c2_len];
+ struct mISDNhead *ctrl = (struct mISDNhead *)buffer;
+ unsigned long *d = buffer+MISDN_HEADER_LEN;
+ int ret;
+
+ ctrl->prim = PH_CONTROL_REQ;
+ ctrl->id = 0;
+ *d++ = c1;
+ memcpy(d, c2, c2_len);
+ ret = sendto(handle, buffer, MISDN_HEADER_LEN+sizeof(int)+c2_len, 0, NULL, 0);
+ if (!ret)
+ PERROR("Failed to send to socket %d\n", handle);
+#else
+ unsigned char buffer[mISDN_HEADER_LEN+sizeof(int)+c2_len];
+ iframe_t *ctrl = (iframe_t *)buffer;
+ unsigned long *d = (unsigned long *)&ctrl->data.p;
+
+ ctrl->prim = PH_CONTROL | REQUEST;
+ ctrl->addr = handle | FLG_MSG_DOWN;
+ ctrl->dinfo = 0;
+ ctrl->len = sizeof(int)+c2_len;
+ *d++ = c1;
+ memcpy(d, c2, c2_len);
+ mISDN_write(bchannel_device, ctrl, mISDN_HEADER_LEN+ctrl->len, TIMEOUT_1SEC);
+#endif
+#if 0
+ chan_trace_header(mISDNport, isdnport, "BCHANNEL control", DIRECTION_OUT);
+ add_trace(trace_name, NULL, "%d", trace_value);
+ end_trace();
+#endif
+}
+
+
+/*
+ * create stack
+ */
+int bchannel_create(struct bchannel *channel)
+{
+ unsigned char buff[1024];
+ int ret;
+#ifdef SOCKET_MISDN
+ unsigned long on = 1;
+ struct sockadd_mISDN addr;
+
+ if (channel->b_sock)
+ {
+ PERROR("Error: Socket already created for handle %d\n", channel->handle);
+ return(0);
+ }
+
+ /* open socket */
+ channel->b_sock = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_L2DSP);
+ if (channel->b_sock < 0)
+ {
+ PERROR("Error: Failed to open bchannel-socket for handle %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", channel->handle);
+ return(0);
+ }
+
+ /* set nonblocking io */
+ ret = ioctl(channel->b_sock, FIONBIO, &on);
+ if (ret < 0)
+ {
+ PERROR("Error: Failed to set bchannel-socket handle %d into nonblocking IO\n", channel->handle);
+ close(channel->b_sock);
+ channel->b_sock = -1;
+ return(0);
+ }
+
+ /* bind socket to bchannel */
+ addr.family = AF_ISDN;
+ addr.dev = (channel->handle>>8)-1;
+ addr.channel = channel->handle && 0xff;
+ ret = bind(di->bchan, (struct sockaddr *)&addr, sizeof(addr));
+ if (ret < 0)
+ {
+ PERROR("Error: Failed to bind bchannel-socket for handle %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", channel->handle);
+ close(channel->b_sock);
+ channel->b_sock = -1;
+ return(0);
+ }
+
+#if 0
+ chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create socket", DIRECTION_OUT);
+ add_trace("channel", NULL, "%d", i+1+(i>=15));
+ add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
+ end_trace();
+#endif
+#else
+ layer_info_t li;
+ mISDN_pid_t pid;
+
+ if (channel->b_stid)
+ {
+ PERROR("Error: stack already created for address 0x%x\n", channel->b_stid);
+ return(0);
+ }
+
+ if (channel->b_addr)
+ {
+ PERROR("Error: stack already created for address 0x%x\n", channel->b_addr);
+ return(0);
+ }
+
+ /* create new layer */
+ PDEBUG("creating new layer for stid 0x%x.\n" , channel->handle);
+ memset(&li, 0, sizeof(li));
+ memset(&pid, 0, sizeof(pid));
+ li.object_id = -1;
+ li.extentions = 0;
+ li.st = channel->handle;
+ strcpy(li.name, "B L4");
+ li.pid.layermask = ISDN_LAYER((4));
+ li.pid.protocol[4] = ISDN_PID_L4_B_USER;
+ ret = mISDN_new_layer(bchannel_device, &li);
+ if (ret)
+ {
+ failed_new_layer:
+ PERROR("mISDN_new_layer() failed to add bchannel for stid 0x%x.\n", channel->handle);
+ goto failed;
+ }
+ if (!li.id)
+ {
+ goto failed_new_layer;
+ }
+ channel->b_stid = channel->handle;
+ channel->b_addr = li.id;
+ PDEBUG("new layer (b_addr=0x%x)\n", channel->b_addr);
+
+ /* create new stack */
+ pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
+ pid.protocol[2] = ISDN_PID_L2_B_TRANS;
+ pid.protocol[3] = ISDN_PID_L3_B_DSP;
+ pid.protocol[4] = ISDN_PID_L4_B_USER;
+ pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
+ ret = mISDN_set_stack(bchannel_device, channel->b_stid, &pid);
+ if (ret)
+ {
+ stack_error:
+ PERROR("mISDN_set_stack() failed (ret=%d) to add bchannel stid=0x%x\n", ret, channel->b_stid);
+ mISDN_write_frame(bchannel_device, buff, channel->b_addr, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
+ goto failed;
+ }
+ ret = mISDN_get_setstack_ind(bchannel_device, channel->b_addr);
+ if (ret)
+ goto stack_error;
+
+ /* get layer id */
+ channel->b_addr = mISDN_get_layerid(bchannel_device, channel->b_stid, 4);
+ if (!channel->b_addr)
+ goto stack_error;
+#if 0
+ chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL create stack", DIRECTION_OUT);
+ add_trace("channel", NULL, "%d", i+1+(i>=15));
+ add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
+ add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
+ end_trace();
+#endif
+#endif
+
+ return(1);
+
+failed:
+ channel->b_stid = 0;
+ channel->b_addr = 0;
+ return(0);
+}
+
+
+/*
+ * activate / deactivate request
+ */
+void bchannel_activate(struct bchannel *channel, int activate)
+{
+#ifdef SOCKET_MISDN
+ struct mISDNhead act;
+ int ret;
+
+ act.prim = (activate)?DL_ESTABLISH_REQ:DL_RELEASE_REQ;
+ act.id = 0;
+ ret = sendto(channel->b_sock, &act, MISDN_HEADER_LEN, 0, NULL, 0);
+ if (!ret)
+ PERROR("Failed to send to socket %d\n", channel->b_sock);
+#else
+ iframe_t act;
+
+ /* activate bchannel */
+ act.prim = (activate?DL_ESTABLISH:DL_RELEASE) | REQUEST;
+ act.addr = channel->b_addr | FLG_MSG_DOWN;
+ act.dinfo = 0;
+ act.len = 0;
+ mISDN_write(bchannel_device, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
+#endif
+
+ channel->b_state = BSTATE_ACTIVATING;
+#if 0
+ /* trace */
+ chan_trace_header(mISDNport, mISDNport->b_port[i], activate?(char*)"BCHANNEL activate":(char*)"BCHANNEL deactivate", DIRECTION_OUT);
+ add_trace("channel", NULL, "%d", i+1+(i>=15));
+ end_trace();
+#endif
+}
+
+
+/*
+ * set features
+ */
+static void bchannel_activated(struct bchannel *channel)
+{
+#ifdef SOCKET_MISDN
+ int handle;
+
+ handle = channel->b_sock;
+#else
+ unsigned long handle;
+
+ handle = channel->b_addr;
+#endif
+
+ /* set dsp features */
+ if (channel->b_txdata)
+ ph_control(handle, (channel->b_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF, 0, "DSP-TXDATA", channel->b_txdata);
+ if (channel->b_delay)
+ ph_control(handle, CMX_DELAY, channel->b_delay, "DSP-DELAY", channel->b_delay);
+ if (channel->b_tx_dejitter)
+ ph_control(handle, (channel->b_tx_dejitter)?CMX_TX_DEJITTER:CMX_TX_DEJ_OFF, 0, "DSP-DELAY", channel->b_tx_dejitter);
+ if (channel->b_tx_gain)
+ ph_control(handle, VOL_CHANGE_TX, channel->b_tx_gain, "DSP-TX_GAIN", channel->b_tx_gain);
+ if (channel->b_rx_gain)
+ ph_control(handle, VOL_CHANGE_RX, channel->b_rx_gain, "DSP-RX_GAIN", channel->b_rx_gain);
+ if (channel->b_pipeline[0])
+ ph_control_block(handle, PIPELINE_CFG, channel->b_pipeline, strlen(channel->b_pipeline)+1, "DSP-PIPELINE", 0);
+ if (channel->b_conf)
+ ph_control(handle, CMX_CONF_JOIN, channel->b_conf, "DSP-CONF", channel->b_conf);
+ if (channel->b_echo)
+ ph_control(handle, CMX_ECHO_ON, 0, "DSP-ECHO", 1);
+ if (channel->b_tone)
+ ph_control(handle, TONE_PATT_ON, channel->b_tone, "DSP-TONE", channel->b_tone);
+ if (channel->b_rxoff)
+ ph_control(handle, CMX_RECEIVE_OFF, 0, "DSP-RXOFF", 1);
+// if (channel->b_txmix)
+// ph_control(handle, CMX_MIX_ON, 0, "DSP-MIX", 1);
+ if (channel->b_dtmf)
+ ph_control(handle, DTMF_TONE_START, 0, "DSP-DTMF", 1);
+ if (channel->b_crypt_len)
+ ph_control_block(handle, BF_ENABLE_KEY, channel->b_crypt_key, channel->b_crypt_len, "DSP-CRYPT", channel->b_crypt_len);
+
+ channel->b_state = BSTATE_ACTIVE;
+}
+
+/*
+ * destroy stack
+ */
+static void bchannel_destroy(struct bchannel *channel)
+{
+#ifdef SOCKET_MISDN
+#if 0
+ chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove socket", DIRECTION_OUT);
+ add_trace("channel", NULL, "%d", i+1+(i>=15));
+ add_trace("socket", NULL, "%d", mISDNport->b_socket[i]);
+ end_trace();
+#endif
+ if (channel->b_sock > -1)
+ {
+ close(channel->b_sock);
+ channel->b_sock = -1;
+ }
+#else
+ unsigned char buff[1024];
+
+#if 0
+ chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL remove stack", DIRECTION_OUT);
+ add_trace("channel", NULL, "%d", i+1+(i>=15));
+ add_trace("stack", "id", "0x%08x", mISDNport->b_stid[i]);
+ add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
+ end_trace();
+#endif
+ /* remove our stack only if set */
+ if (channel->b_addr)
+ {
+ PDEBUG("free stack (b_addr=0x%x)\n", channel->b_addr);
+ mISDN_clear_stack(bchannel_device, channel->b_stid);
+ mISDN_write_frame(bchannel_device, buff, channel->b_addr | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
+ channel->b_stid = 0;
+ channel->b_addr = 0;
+ }
+#endif
+ channel->b_state = BSTATE_IDLE;
+}
+
+
+/*
+ * whenever we get audio data from bchannel, we process it here
+ */
+static void bchannel_receive(struct bchannel *channel, unsigned long prim, unsigned long dinfo, unsigned char *data, int len)
+{
+ unsigned long cont = *((unsigned long *)data);
+ unsigned char *data_temp;
+ unsigned long length_temp;
+ unsigned char *p;
+ int l;
+
+ if (prim == (PH_CONTROL | INDICATION))
+ {
+ if (len < 4)
+ {
+ PERROR("SHORT READ OF PH_CONTROL INDICATION\n");
+ return;
+ }
+ if ((cont&(~DTMF_TONE_MASK)) == DTMF_TONE_VAL)
+ {
+#if 0
+ chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
+ add_trace("DTMF", NULL, "%c", cont & DTMF_TONE_MASK);
+ end_trace();
+#endif
+ if (channel->rx_dtmf)
+ channel->rx_dtmf(channel, cont & DTMF_TONE_MASK);
+ return;
+ }
+ switch(cont)
+ {
+ case BF_REJECT:
+#if 0
+ chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
+ add_trace("DSP-CRYPT", NULL, "error");
+ end_trace();
+#endif
+ break;
+
+ case BF_ACCEPT:
+#if 0
+ chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
+ add_trace("DSP-CRYPT", NULL, "ok");
+ end_trace();
+#endif
+ break;
+
+ default:
+#if 0
+ chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
+ add_trace("unknown", NULL, "0x%x", cont);
+ end_trace();
+#else
+ ;
+#endif
+ }
+ return;
+ }
+ if (prim == (PH_SIGNAL | INDICATION))
+ {
+ switch(dinfo)
+ {
+ case CMX_TX_DATA:
+ if (!channel->b_txdata)
+ {
+ /* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
+ PDEBUG("PmISDN(%s) ignoring tx data, because 'txdata' is turned off\n", p_name);
+ return;
+ }
+ break;
+
+ default:
+#if 0
+ chan_trace_header(p_m_mISDNport, this, "BCHANNEL signal", DIRECTION_IN);
+ add_trace("unknown", NULL, "0x%x", frm->dinfo);
+ end_trace();
+#else
+ ;
+#endif
+ }
+ return;
+ }
+ if (prim != PH_DATA_IND && prim != DL_DATA_IND)
+ {
+ PERROR("Bchannel received unknown primitve: 0x%x\n", prim);
+ return;
+ }
+ /* calls will not process any audio data unless
+ * the call is connected OR interface features audio during call setup.
+ */
+
+ /* if rx is off, it may happen that fifos send us pending informations, we just ignore them */
+ if (channel->b_rxoff)
+ {
+ PDEBUG("PmISDN(%s) ignoring data, because rx is turned off\n", p_name);
+ return;
+ }
+
+ if (channel->rx_data)
+ channel->rx_data(channel, data, len);
+}
+
+
+/*
+ * transmit data to bchannel
+ */
+void bchannel_transmit(struct bchannel *channel, unsigned char *data, int len)
+{
+ unsigned char buff[1025];
+ iframe_t *frm = (iframe_t *)buff;
+
+ if (channel->b_state != BSTATE_ACTIVE)
+ return;
+#ifdef SOCKET_MISDN
+ frm->prim = DL_DATA_REQ;
+ frm->id = 0;
+ ret = sendto(channel->b_sock, data, len, 0, NULL, 0);
+ if (!ret)
+ PERROR("Failed to send to socket %d\n", channel->b_sock);
+#else
+ frm->prim = DL_DATA | REQUEST;
+ frm->addr = channel->b_addr | FLG_MSG_DOWN;
+ frm->dinfo = 0;
+ frm->len = len;
+ if (frm->len)
+ mISDN_write(bchannel_device, frm, mISDN_HEADER_LEN+frm->len, TIMEOUT_1SEC);
+#endif
+}
+
+
+/*
+ * join bchannel
+ */
+void bchannel_join(struct bchannel *channel, unsigned short id)
+{
+#ifdef SOCKET_MISDN
+ int handle;
+
+ handle = channel->b_sock;
+#else
+ unsigned long handle;
+
+ handle = channel->b_addr;
+#endif
+ if (id)
+ channel->b_conf = (id<<16) + bchannel_pid;
+ else
+ channel->b_conf = 0;
+ if (channel->b_state == BSTATE_ACTIVE)
+ ph_control(handle, CMX_CONF_JOIN, channel->b_conf, "DSP-CONF", channel->b_conf);
+}
+
+
+/*
+ * main loop for processing messages from mISDN
+ */
+#ifdef SOCKET_MISDN
+int bchannel_handle(void)
+{
+ int ret, work = 0;
+ struct bchannel *channel;
+ int i;
+ char buffer[2048+MISDN_HEADER_LEN];
+ struct mISDNhead *hh = (struct mISDNhead *)buffer;
+
+ /* process all bchannels */
+ channel = bchannel_first;
+ while(channel)
+ {
+ /* handle message from bchannel */
+ if (channel->b_sock > -1)
+ {
+ ret = recv(channel->b_sock, buffer, sizeof(buffer), 0);
+ if (ret >= MISDN_HEADER_LEN)
+ {
+ work = 1;
+ switch(hh->prim)
+ {
+ /* we don't care about confirms, we use rx data to sync tx */
+ case PH_DATA_CONF:
+ case DL_DATA_CONF:
+ break;
+
+ /* we receive audio data, we respond to it AND we send tones */
+ case PH_DATA_IND:
+ case DL_DATA_IND:
+ case PH_SIGNAL_IND:
+ case PH_CONTROL | INDICATION:
+ bchannel_receive(channel, hh->prim, hh->dinfo, buffer+MISDN_HEADER_LEN, ret-MISDN_HEADER_LEN);
+ break;
+
+ case PH_ACTIVATE_IND:
+ case DL_ESTABLISH_IND:
+ case PH_ACTIVATE_CONF:
+ case DL_ESTABLISH_CONF:
+ PDEBUG("DL_ESTABLISH confirm: bchannel is now activated (socket %d).\n", channel->b_sock);
+ bchannel_activated(channel);
+ break;
+
+ case PH_DEACTIVATE_IND:
+ case DL_RELEASE_IND:
+ case PH_DEACTIVATE_CONF:
+ case DL_RELEASE_CONF:
+ PDEBUG("DL_RELEASE confirm: bchannel is now de-activated (socket %d).\n", channel->b_sock);
+// bchannel_deactivated(channel);
+ break;
+
+ default:
+ PERROR("child message not handled: prim(0x%x) socket(%d) msg->len(%d)\n", hh->prim, channel->b_sock, msg->len);
+ }
+ } else
+ {
+ if (ret < 0 && errno != EWOULDBLOCK)
+ PERROR("Read from socket %d failed with return code %d\n", channel->b_sock, ret);
+ }
+ }
+ channel = channel->next;
+ }
+
+ /* if we received at least one b-frame, we will return 1 */
+ return(work);
+}
+#else
+int bchannel_handle(void)
+{
+ int ret;
+ int i;
+ struct bchannel *channel;
+ msg_t *msg;
+ iframe_t *frm;
+ msg_t *dmsg;
+ mISDNuser_head_t *hh;
+ net_stack_t *nst;
+
+ /* no device, no read */
+ if (bchannel_device < 0)
+ return(0);
+
+ /* get message from kernel */
+ if (!(msg = alloc_msg(MAX_MSG_SIZE)))
+ return(1);
+ ret = mISDN_read(bchannel_device, msg->data, MAX_MSG_SIZE, 0);
+ if (ret < 0)
+ {
+ free_msg(msg);
+ if (errno == EAGAIN)
+ return(0);
+ FATAL("Failed to do mISDN_read()\n");
+ }
+ if (!ret)
+ {
+ free_msg(msg);
+// printf("%s: ERROR: mISDN_read() returns nothing\n");
+ return(0);
+ }
+ msg->len = ret;
+ frm = (iframe_t *)msg->data;
+
+ /* global prim */
+ switch(frm->prim)
+ {
+ case MGR_DELLAYER | CONFIRM:
+ case MGR_INITTIMER | CONFIRM:
+ case MGR_ADDTIMER | CONFIRM:
+ case MGR_DELTIMER | CONFIRM:
+ case MGR_REMOVETIMER | CONFIRM:
+ free_msg(msg);
+ return(1);
+ }
+
+ /* find the mISDNport that belongs to the stack */
+ channel = bchannel_first;
+ while(channel)
+ {
+ if (frm->addr == channel->b_addr)
+ break;
+ channel = channel->next;
+ }
+ if (!channel)
+ {
+ PERROR("message belongs to no channel: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
+ goto out;
+ }
+
+ /* b-message */
+ switch(frm->prim)
+ {
+ /* we don't care about confirms, we use rx data to sync tx */
+ case PH_DATA | CONFIRM:
+ case DL_DATA | CONFIRM:
+ break;
+
+ /* we receive audio data, we respond to it AND we send tones */
+ case PH_DATA | INDICATION:
+ case DL_DATA | INDICATION:
+ case PH_CONTROL | INDICATION:
+ case PH_SIGNAL | INDICATION:
+ bchannel_receive(channel, frm->prim, frm->dinfo, frm->data.p, frm->len);
+ break;
+
+ case PH_ACTIVATE | INDICATION:
+ case DL_ESTABLISH | INDICATION:
+ case PH_ACTIVATE | CONFIRM:
+ case DL_ESTABLISH | CONFIRM:
+ PDEBUG( "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
+ bchannel_activated(channel);
+ break;
+
+ case PH_DEACTIVATE | INDICATION:
+ case DL_RELEASE | INDICATION:
+ case PH_DEACTIVATE | CONFIRM:
+ case DL_RELEASE | CONFIRM:
+ PDEBUG("DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
+// bchannel_deactivated(channel);
+ break;
+
+ default:
+ PERROR("message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
+ }
+
+ out:
+ free_msg(msg);
+ return(1);
+}
+#endif
+
+
+/*
+ * bchannel channel handling
+ */
+struct bchannel *bchannel_first = NULL;
+struct bchannel *find_bchannel_handle(unsigned long handle)
+{
+ struct bchannel *channel = bchannel_first;
+
+ while(channel)
+ {
+ if (channel->handle == handle)
+ break;
+ channel = channel->next;
+ }
+ return(channel);
+}
+
+struct bchannel *find_bchannel_ref(unsigned long ref)
+{
+ struct bchannel *channel = bchannel_first;
+
+ while(channel)
+ {
+ if (channel->ref == ref)
+ break;
+ channel = channel->next;
+ }
+ return(channel);
+}
+
+struct bchannel *alloc_bchannel(unsigned long handle)
+{
+ struct chan_bchannel **channelp = &bchannel_first;
+
+ while(*channelp)
+ channelp = &((*channelp)->next);
+
+ *channelp = (struct chan_bchannel *)malloc(sizeof(struct chan_bchannel));
+ if (!*channelp)
+ return(NULL);
+ channel->handle = handle;
+ channel->b_state = BSTATE_IDLE;
+
+ return(*channelp);
+}
+
+void free_bchannel(struct bchannel *channel)
+{
+ struct bchannel **temp = &bchannel_first;
+
+ while(*temp)
+ {
+ if (*temp == channel)
+ {
+ *temp = (*temp)->next;
+#ifdef SOCKET_MISDN
+ if (channel->b_sock > -1)
+#else
+ if (channel->b_stid)
+#endif
+ bchannel_destroy(channel);
+ free(channel);
+ return;
+ }
+ temp = &((*temp)->next);
+ }
+}
+
+
--- /dev/null
+/*****************************************************************************\
+** **
+** Linux Call Router **
+** **
+**---------------------------------------------------------------------------**
+** Copyright: Andreas Eversberg **
+** **
+** mISDN channel handlin for remote application **
+** **
+\*****************************************************************************/
+
+
+struct bchannel {
+ struct bchannel *next;
+ unsigned long ref; /* ref for link to call process */
+ unsigned long handle; /* handle for stack id */
+#ifdef SOCKET_MISDN
+ int b_sock; /* socket for b-channel */
+#else
+ unsigned long b_stid; /* stack id */
+ unsigned long b_addr; /* channel address */
+#endif
+ int b_state;
+ int b_txdata;
+ int b_delay;
+ int b_tx_dejitter;
+ int b_tx_gain, b_rx_gain;
+ char b_pipeline[256];
+ unsigned long b_conf;
+ int b_echo;
+ int b_tone;
+ int b_rxoff;
+ // int b_txmix;
+ int b_dtmf;
+ int b_crypt_len;
+ int b_crypt_type;
+ unsigned char b_crypt_key[128];
+
+ void (*rx_data)(struct bchannel *bchannel, unsigned char *data, int len);
+ void (*rx_dtmf)(struct bchannel *bchannel, char tone);
+};
+
+
+extern struct bchannel *bchannel_first;
+
+int bchannel_initialize(void);
+void bchannel_deinitialize(void);
+int bchannel_create(struct bchannel *channel);
+void bchannel_activate(struct bchannel *channel, int activate);
+void bchannel_transmit(struct bchannel *channel, unsigned char *data, int len);
+void bchannel_join(struct bchannel *channel, unsigned short id);
+int bchannel_handle(void);
+struct bchannel *bchannel_first = NULL;
+struct bchannel *find_bchannel_handle(unsigned long handle);
+struct bchannel *find_bchannel_ref(unsigned long ref);
+struct bchannel *alloc_bchannel(unsigned long handle);
+void free_bchannel(struct bchannel *channel);
+
#include "message.h"
#include "admin.h"
#include "cause.h"
-#include "asterisk_client.h"
+#include "bchannel.h"
+#include "chan_lcr.h"
int sock;
/*
* channel and call instances
*/
-struct chan_bchannel *bchannel_first;
struct chan_call *call_first;
-struct chan_bchannel *find_bchannel_handle(unsigned long addr)
-{
- struct chan_bchannel *bchannel = bchannel_first;
-
- while(bchannel)
- {
- if (bchannel->addr == addr)
- break;
- bchannel = bchannel->next;
- }
- return(bchannel);
-}
-
-struct chan_bchannel *find_bchannel_ref(unsigned long ref)
-{
- struct chan_bchannel *bchannel = bchannel_first;
-
- while(bchannel)
- {
- if (bchannel->ref == ref)
- break;
- bchannel = bchannel->next;
- }
- return(bchannel);
-}
-
struct chan_call *find_call_ref(unsigned long ref)
{
struct chan_call *call = call_first;
return(call);
}
-struct chan_call *find_call_addr(unsigned long addr)
+struct chan_call *find_call_handle(unsigned long handle)
{
struct chan_call *call = call_first;
while(call)
{
- if (call->addr == addr)
+ if (call->bchannel_handle == handle)
break;
call = call->next;
}
return(call);
}
-struct chan_bchannel *alloc_bchannel(void)
-{
- struct chan_bchannel **bchannelp = &bchannel_first;
-
- while(*bchannelp)
- bchannelp = &((*bchannelp)->next);
-
- *bchannelp = (struct chan_bchannel *)MALLOC(sizeof(struct chan_bchannel));
- return(*bchannelp);
-}
-
-void free_bchannel(struct chan_bchannel *bchannel)
-{
- struct chan_bchannel **temp = &bchannel_first;
-
- while(*temp)
- {
- if (*temp == bchannel)
- {
- *temp = (*temp)->next;
- free(bchannel);
- return;
- }
- temp = &((*temp)->next);
- }
-}
-
struct chan_call *alloc_call(void)
{
struct chan_call **callp = &call_first;
/*
+ * receive bchannel data
+ */
+void rx_data(struct bchannel *bchannel, unsigned char *data, int len)
+{
+}
+
+void rx_dtmf(struct bchannel *bchannel, char tone)
+{
+}
+
+/*
* enque message to LCR
*/
int send_message(int message_type, unsigned long ref, union parameter *param)
int receive_message(int message_type, unsigned long ref, union parameter *param)
{
union parameter newparam;
- struct chan_bchannel *bchannel;
+ struct bchannel *bchannel;
struct chan_call *call;
memset(&newparam, 0, sizeof(union parameter));
return(-1);
}
/* create bchannel */
- bchannel = alloc_bchannel();
- bchannel->addr = param->bchannel.handle;
+ bchannel = alloc_bchannel(param->bchannel.handle);
+ if (!bchannel)
+ {
+ fprintf(stderr, "error: alloc bchannel handle %x failed.\n", param->bchannel.handle);
+ return(-1);
+ }
+
+ /* configure channel */
+ bchannel->b_tx_gain = param->bchannel.tx_gain;
+ bchannel->b_rx_gain = param->bchannel.rx_gain;
+ strncpy(bchannel->b_pipeline, param->bchannel.pipeline, sizeof(bchannel->b_pipeline)-1);
+ if (param->bchannel.crypt_len)
+ {
+ bchannel->b_crypt_len = param->bchannel.crypt_len;
+ bchannel->b_crypt_type = param->bchannel.crypt_type;
+ memcpy(bchannel->b_crypt_key, param->bchannel.crypt, param->bchannel.crypt_len);
+ }
+ bchannel->b_txdata = 0;
+ bchannel->b_dtmf = 1;
+ bchannel->b_tx_dejitter = 1;
+
/* in case, ref is not set, this bchannel instance must
* be created until it is removed again by LCR */
/* link to call */
if ((call = find_call_ref(ref)))
{
bchannel->ref = ref;
- call->addr = param->bchannel.handle;
+ call->bchannel_handle = param->bchannel.handle;
}
+ if (bchannel_create(bchannel))
+ bchannel_activate(bchannel, 1);
-#warning open stack
/* acknowledge */
newparam.bchannel.type = BCHANNEL_ASSIGN_ACK;
newparam.bchannel.handle = param->bchannel.handle;
/* unlink from call */
if ((call = find_call_ref(bchannel->ref)))
{
- call->addr = 0;
+ call->bchannel_handle = 0;
}
- /* remove bchannel */
+ /* destroy and remove bchannel */
free_bchannel(bchannel);
-#warning close stack
+
/* acknowledge */
newparam.bchannel.type = BCHANNEL_REMOVE_ACK;
newparam.bchannel.handle = param->bchannel.handle;
int ret;
unsigned long on = 1;
union parameter param;
+ int work;
/* open socket */
if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
SCPY(param.hello.application, "asterisk");
send_message(MESSAGE_HELLO, 0, ¶m);
+ /* bchannel */
+ if (!bchannel_initialize())
+ goto bchannel_failed;
+
while(42)
{
+ work = 0;
+
+ /* handle socket */
ret = handle_socket();
if (ret < 0)
break;
- if (!ret)
+ if (ret)
+ work = 1;
+
+ /* handle mISDN */
+ ret = bchannel_handle();
+ if (ret)
+ work = 1;
+
+ if (!work)
usleep(30000);
}
+
+ bchannel_deinitialize();
+ bchannel_failed:
/* close socket */
close(sock);
struct chan_call {
struct chan_call *next;
unsigned long ref; /* callref, is 0, if not yet set */
- unsigned long addr; /* reference to bchannel, if set */
+ unsigned long bchannel_handle; /* reference to bchannel, if set */
};
-/* structure of all bchannels (that are assinged by lcr) */
-struct chan_bchannel {
- struct chan_bchannel *next;
- unsigned long addr; /* stack address */
- unsigned long ref; /* if linked with a call, ref is set */
-};
+++ /dev/null
-/*****************************************************************************\
-** **
-** Linux Call Router **
-** **
-**---------------------------------------------------------------------------**
-** Copyright: Andreas Eversberg **
-** **
-** mISDN bchannel access (for Asterisk) **
-** **
-\*****************************************************************************/
-
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include "main.h"
-#include <unistd.h>
-#include <poll.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-extern "C" {
-#include <net_l2.h>
-}
-
-#if 0
-#ifndef ISDN_PID_L2_B_USER
-#define ISDN_PID_L2_B_USER 0x420000ff
-#endif
-#ifndef ISDN_PID_L3_B_USER
-#define ISDN_PID_L3_B_USER 0x430000ff
-#endif
-#endif
-#ifndef ISDN_PID_L4_B_USER
-#define ISDN_PID_L4_B_USER 0x440000ff
-#endif
-
-/* used for udevice */
-int entity = 0;
-
-/* the device handler and port list */
-int mISDNdevice = -1;
-
-
-/* open mISDN device */
-void mISDNdevice_open(void)
-{
- /* open mISDNdevice if not already open */
- if (mISDNdevice < 0)
- {
- ret = mISDN_open();
- if (ret < 0)
- {
- PERROR("cannot open mISDN device ret=%d errno=%d (%s) Check for mISDN modules!\nAlso did you create \"/dev/mISDN\"? Do: \"mknod /dev/mISDN c 46 0\"\n", ret, errno, strerror(errno));
- return(NULL);
- }
- mISDNdevice = ret;
- PDEBUG(DEBUG_ISDN, "mISDN device opened.\n");
- }
-}
-
-/* close mISDN device */
-void mISDNdevice_close(void)
-{
- if (mISDNdevice > -1)
- {
- mISDN_close();
- PDEBUG(DEBUG_ISDN, "mISDN device closed.\n");
- }
-}
-
-/* create bchannel layer */
-unsigned long mISDN_createlayer(unsigned long stid)
-{
- unsigned long addr;
-
- /* create new layer */
- PDEBUG(DEBUG_BCHANNEL, "creating new layer for bchannel stid=0%x.\n" , stid);
- memset(&li, 0, sizeof(li));
- memset(&pid, 0, sizeof(pid));
- li.object_id = -1;
- li.extentions = 0;
- li.st = stid;
- UCPY(li.name, "B L4");
- li.pid.layermask = ISDN_LAYER((4));
- li.pid.protocol[4] = ISDN_PID_L4_B_USER;
- ret = mISDN_new_layer(mISDNdevice, &li);
- if (ret)
- {
- failed_new_layer:
- PERROR("mISDN_new_layer() failed to add bchannel stid=0%x.\n", stid);
- goto failed;
- }
- addr = li.id;
- if (!li.id)
- {
- goto failed_new_layer;
- }
- PDEBUG(DEBUG_BCHANNEL, "new layer (addr=0x%x)\n", addr);
-
- /* create new stack */
- pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
- pid.protocol[2] = ISDN_PID_L2_B_TRANS;
- pid.protocol[3] = ISDN_PID_L3_B_DSP;
- pid.protocol[4] = ISDN_PID_L4_B_USER;
- pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
- ret = mISDN_set_stack(mISDNdevice, stid, &pid);
- if (ret)
- {
- stack_error:
- PERROR("mISDN_set_stack() failed (ret=%d) to add bchannel stid=0x%x\n", ret, stid);
- mISDN_write_frame(mISDNdevice, buff, addr, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
- goto failed;
- }
- ret = mISDN_get_setstack_ind(mISDNdevice, addr);
- if (ret)
- goto stack_error;
-
- /* get layer id */
- addr = mISDN_get_layerid(mISDNdevice, stid, 4);
- if (!addr)
- goto stack_error;
-}
-
-/* destroy bchannel layer */
-void mISDN_destroylayer(unsigned long stid, unsigned long addr)
-{
- /* remove our stack only if set */
- if (addr)
- {
- PDEBUG(DEBUG_BCHANNEL, "free stack (addr=0x%x)\n", addr);
- mISDN_clear_stack(mISDNdevice, stid);
- mISDN_write_frame(mISDNdevice, buff, addr | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
- }
-}
-
-/* do activation and deactivation of bchannel */
-static void mISDN_bchannelactivate(unsigned long addr, int activate)
-{
- iframe_t act;
-
- /* activate bchannel */
- act.prim = (activate?DL_ESTABLISH:DL_RELEASE) | REQUEST;
- act.addr = addr | FLG_MSG_DOWN;
- act.dinfo = 0;
- act.len = 0;
- mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
-}
-
-/* handle all mISDN messages */
-int mISDN_handler(void)
-{
- int ret;
- msg_t *msg;
- iframe_t *frm;
- struct mISDNport *mISDNport;
- class PmISDN *isdnport;
- net_stack_t *nst;
- msg_t *dmsg;
- mISDNuser_head_t *hh;
- int i;
- struct chan_bchannel *bchannel;
-
- /* no device, no read */
- if (mISDNdevice < 0)
- return(0);
-
- /* get message from kernel */
- if (!(msg = alloc_msg(MAX_MSG_SIZE)))
- return(1);
- ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
- if (ret < 0)
- {
- free_msg(msg);
- if (errno == EAGAIN)
- return(0);
- FATAL("Failed to do mISDN_read()\n");
- }
- if (!ret)
- {
- free_msg(msg);
-// printf("%s: ERROR: mISDN_read() returns nothing\n");
- return(0);
- }
- msg->len = ret;
- frm = (iframe_t *)msg->data;
-
- /* global prim */
- switch(frm->prim)
- {
- case MGR_DELLAYER | CONFIRM:
- case MGR_INITTIMER | CONFIRM:
- case MGR_ADDTIMER | CONFIRM:
- case MGR_DELTIMER | CONFIRM:
- case MGR_REMOVETIMER | CONFIRM:
- free_msg(msg);
- return(1);
- }
-
- /* look for channel instance, that has the address of this message */
- bchannel = bchannel_first;
- while(bchannel)
- {
- if (frm->addr == bchannel->b_addr)
- break;
- bchannel = chan->next;
- }
- if (!bchannel)
- {
- PERROR("message belongs to no bchannel: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
- goto out;
- }
-
- /* b-message */
- switch(frm->prim)
- {
- /* we don't care about confirms, we use rx data to sync tx */
- case PH_DATA | CONFIRM:
- case DL_DATA | CONFIRM:
- break;
-
- /* we receive audio data, we respond to it AND we send tones */
- case PH_DATA | INDICATION:
- case DL_DATA | INDICATION:
- case PH_CONTROL | INDICATION:
- i = 0;
- bchannel_receive(bchannel, frm);
- break;
-
- case PH_ACTIVATE | INDICATION:
- case DL_ESTABLISH | INDICATION:
- case PH_ACTIVATE | CONFIRM:
- case DL_ESTABLISH | CONFIRM:
- PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
- bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
- break;
-
- case PH_DEACTIVATE | INDICATION:
- case DL_RELEASE | INDICATION:
- case PH_DEACTIVATE | CONFIRM:
- case DL_RELEASE | CONFIRM:
- PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
- bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
- break;
-
- default:
- PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
- }
-
- out:
- free_msg(msg);
- return(1);
-}
-
/*
- * hunt bchannel for incomming setup or retrieve or resume
+ * hunt bchannel for incoming setup or retrieve or resume
*/
int Pdss1::hunt_bchannel(int channel, int exclusive)
{
FATAL("Incoming call but already got an endpoint.\n");
if (!(epoint = new Endpoint(p_serial, 0)))
FATAL("No memory for Endpoint instance\n");
- if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint, 0))) //incomming
+ if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint, 0))) //incoming
FATAL("No memory for Endpoint Application instance\n");
epointlist_new(epoint->ep_serial);
char *p = NULL;
/*
- * we may only release during incomming disconnect state.
+ * we may only release during incoming disconnect state.
* this means that the endpoint doesnt require audio anymore
*/
if (p_state == PORT_STATE_IN_DISCONNECT
PDEBUG(DEBUG_CONFIG, "given noknocking param unknown: %s\n", param);
}
} else
- if (!strcmp(option,"rxvol"))
+ if (!strcmp(option,"rx_gain")
+ || !strcmp(option,"rxvol"))
{
- ext->rxvol = atoi(param);
- if (ext->rxvol<-8 || ext->rxvol>8)
- ext->rxvol = 0;
+ ext->rx_gain = atoi(param);
+ if (ext->rx_gain<-8 || ext->rx_gain>8)
+ ext->rx_gain = 0;
- PDEBUG(DEBUG_CONFIG, "receive volume: %d\n",ext->rxvol);
+ PDEBUG(DEBUG_CONFIG, "receive volume: %d\n",ext->rx_gain);
} else
- if (!strcmp(option,"txvol"))
+ if (!strcmp(option,"tx_gain")
+ || !strcmp(option,"txvol"))
{
- ext->txvol = atoi(param);
- if (ext->txvol<-8 || ext->txvol>8)
- ext->txvol = 0;
+ ext->tx_gain = atoi(param);
+ if (ext->tx_gain<-8 || ext->tx_gain>8)
+ ext->tx_gain = 0;
- PDEBUG(DEBUG_CONFIG, "transmit volume: %d\n",ext->txvol);
+ PDEBUG(DEBUG_CONFIG, "transmit volume: %d\n",ext->tx_gain);
} else
if (!strcmp(option,"own_setup"))
{
}
fprintf(fp,"# CLIP Prefix\n");
- fprintf(fp,"# Adds a prefix to incomming caller IDs, so telephones will be able to respond\n");
+ fprintf(fp,"# Adds a prefix to incoming caller IDs, so telephones will be able to respond\n");
fprintf(fp,"# to unanswered calls from their list. The prefix must be the digit(s) to get\n");
fprintf(fp,"# an external line. The caller ID will then be extendet so that they can be\n");
fprintf(fp,"# dialed from internal telephones. Many telephones have this feature, but some\n");
fprintf(fp,"# 1 = double, 2 = quadrupel, 8 = 256 times (amplitude)\n");
fprintf(fp,"# -1 = half, -2 = quarter, 8 = 1/256th (amplitude)\n");
fprintf(fp,"# Audio data is limited to the maximum value when exceeds limit.\n");
- fprintf(fp,"txvol %d\n\n",ext->txvol);
+ fprintf(fp,"tx_gain %d\n\n",ext->tx_gain);
fprintf(fp,"# Receive volume (-8 .. 8)\n");
- fprintf(fp,"# (see txvol)\n");
- fprintf(fp,"rxvol %d\n\n",ext->rxvol);
+ fprintf(fp,"# (see tx_gain)\n");
+ fprintf(fp,"rx_gain %d\n\n",ext->rx_gain);
fprintf(fp,"# Force to use tones and announcements generated by the pbx.\n");
int change_callerid;
int clip; /* how to present caller id on forwarded calls */
int colp; /* how to present called line id on forwarded calls */
- char clip_prefix[32]; /* prefix for screening incomming clip */
+ char clip_prefix[32]; /* prefix for screening incoming clip */
int keypad; /* support keypad for call control */
int centrex; /* present name of caller/called on internal extension */
int anon_ignore; /* ignore anonymouse calls */
int noknocking; /* deny knocking of incoming call */
char last_out[MAX_REMEMBER][64]; /* numbers to redail */
char last_in[MAX_REMEMBER][64]; /* numbers to reply */
- int txvol;
- int rxvol;
+ int tx_gain;
+ int rx_gain;
int display_cause; /* clear cause using display message */
int display_ext; /* display external caller ids */
int display_int; /* display internal caller ids */
SPRINT(interface_error, "Error in %s (line %d): parameter '%s %s' gain values not in range. (-8...8)\n", filename, line, parameter, value);
return(-1);
}
- interface->gain_tx = atoi(p);
- interface->gain_rx = atoi(q);
+ interface->tx_gain = atoi(p);
+ interface->rx_gain = atoi(q);
} else
if (!strcasecmp(value, "pipeline"))
{
" no - Signal 'no channel available' aka 'call waiting'. (see DSS1)"},
{"channel-in", &inter_channel_in, "[<number>][,...][,free]",
- "Channel selection list for all incomming calls from the interface.\n"
+ "Channel selection list for all incoming calls from the interface.\n"
"A free channels is accepted if in the list.\n"
"If any channel was requested, the first free channel found is selected.\n"
"This parameter must follow a 'port' parameter.\n"
" free - Accept any free channel"},
{"timeouts", &inter_timeouts, "<setup> <dialing> <proceeding> <alerting> <disconnect>",
- "Timeout values for call states. They are both for incomming and outgoing states.\n"
+ "Timeout values for call states. They are both for incoming and outgoing states.\n"
"The default is 120 seconds for all states. Use 0 to disable.\n"
"This parameter must follow a 'port' parameter.\n"},
{"msn", &inter_msn, "<default MSN>,[<additional MSN>[,...]]",
- "Incomming caller ID is checked against given MSN numbers.\n"
+ "Incoming caller ID is checked against given MSN numbers.\n"
"If the caller ID is not found in this list, it is overwritten by the first MSN"},
{"screen-in", &inter_screen_in, "[options] <old caller ID>[%] [options] <new caller ID>[%]",
- "Adds an entry for incomming calls to the caller ID screen list.\n"
+ "Adds an entry for incoming calls to the caller ID screen list.\n"
"If the given 'old caller ID' matches, it is replaced by the 'new caller ID'\n"
"If '%' is given after old caller ID, it matches even if caller ID has\n"
"additional digits.\n"
/* screen caller id
- * out==0: incomming caller id, out==1: outgoing caller id
+ * out==0: incoming caller id, out==1: outgoing caller id
*/
void do_screen(int out, char *id, int idsize, int *type, int *present, struct interface *interface)
{
struct interface_msn *ifmsn; /* link to interface msn list */
struct interface_screen *ifscreen_in; /* link to screening list */
struct interface_screen *ifscreen_out; /* link to screening list */
- int gain_tx, gain_rx; /* filter gain */
+ int tx_gain, rx_gain; /* filter gain */
char pipeline[256]; /* filter pipeline */
unsigned char bf_key[56]; /* filter blowfish */
int bf_len; /* filter length of blowfish */
}
}
-void message_bchannel_to_join(unsigned long remote_id, unsigned long ref, int type, unsigned long handle)
+void message_bchannel_to_join(unsigned long remote_id, unsigned long ref, int type, unsigned long handle, int tx_gain, int rx_gain, char *pipeline, unsigned char *crypt, int crypt_len, int crypt_type)
{
union parameter param;
memset(¶m, 0, sizeof(union parameter));
param.bchannel.type = type;
param.bchannel.handle = handle;
+ param.bchannel.tx_gain = tx_gain;
+ param.bchannel.rx_gain = rx_gain;
+ if (pipeline)
+ SCPY(param.bchannel.pipeline, pipeline);
+ if (crypt_len)
+ memcpy(param.bchannel.crypt, crypt, crypt_len);
+ param.bchannel.crypt_type = crypt_type;
if (admin_message_from_join(remote_id, ref, MESSAGE_BCHANNEL, ¶m)<0)
{
PERROR("No socket with remote id %d found, this happens, if the socket is closed before all bchannels are imported.\n", remote_id);
};
-void message_bchannel_to_join(unsigned long remote_id, unsigned long ref, int type, unsigned long handle);
+void message_bchannel_to_join(unsigned long remote_id, unsigned long ref, int type, unsigned long handle, int tx_gain, int rx_gain, char *pipeline, unsigned char *crypt, int crypt_len, int crypt_type);
p_m_b_reserve = 0;
p_m_delete = 0;
p_m_hold = 0;
- p_m_txvol = mISDNport->ifport->interface->gain_tx;
- p_m_rxvol = mISDNport->ifport->interface->gain_rx;
+ p_m_tx_gain = mISDNport->ifport->interface->tx_gain;
+ p_m_rx_gain = mISDNport->ifport->interface->rx_gain;
p_m_conf = 0;
p_m_txdata = 0;
p_m_delay = 0;
/* open socket */
mISDNport->b_socket[i] = socket(PF_ISDN, SOCK_DGRAM, ISDN_P_B_L2DSP);
- if (mISDNport->b_socket[i])
+ if (mISDNport->b_socket[i] < 0)
{
PERROR("Error: Failed to open bchannel-socket for index %d with mISDN-DSP layer. Did you load mISDNdsp.ko?\n", i);
return(0);
ph_control(mISDNport, port, handle, (port->p_m_txdata)?CMX_TXDATA_ON:CMX_TXDATA_OFF, 0, "DSP-TXDATA", port->p_m_txdata);
if (port->p_m_delay)
ph_control(mISDNport, port, handle, CMX_DELAY, port->p_m_delay, "DSP-DELAY", port->p_m_delay);
- if (port->p_m_txvol)
- ph_control(mISDNport, port, handle, VOL_CHANGE_TX, port->p_m_txvol, "DSP-TXVOL", port->p_m_txvol);
- if (port->p_m_rxvol)
- ph_control(mISDNport, port, handle, VOL_CHANGE_RX, port->p_m_rxvol, "DSP-RXVOL", port->p_m_rxvol);
+ if (port->p_m_tx_gain)
+ ph_control(mISDNport, port, handle, VOL_CHANGE_TX, port->p_m_tx_gain, "DSP-TX_GAIN", port->p_m_tx_gain);
+ if (port->p_m_rx_gain)
+ ph_control(mISDNport, port, handle, VOL_CHANGE_RX, port->p_m_rx_gain, "DSP-RX_GAIN", port->p_m_rx_gain);
if (port->p_m_pipeline[0])
ph_control_block(mISDNport, port, handle, PIPELINE_CFG, port->p_m_pipeline, strlen(port->p_m_pipeline)+1, "DSP-PIPELINE", 0);
if (port->p_m_conf)
int state = mISDNport->b_state[i];
unsigned long p_m_remote_ref = 0;
unsigned long p_m_remote_id = 0;
+ int p_m_tx_gain = 0;
+ int p_m_rx_gain = 0;
+ char *p_m_pipeline = NULL;
+ unsigned char *p_m_crypt_key = NULL;
+ int p_m_crypt_key_len = 0;
+ int p_m_crypt_key_type = 0;
#ifdef SOCKET_MISDN
unsigned long portid = (mISDNport->portnum<<8) + i+1+(i>=15);
#else
- unsigned long portid = mISDNport->b_addr[i];
+ unsigned long portid = mISDNport->b_stid[i];
#endif
if (b_port)
{
p_m_remote_id = b_port->p_m_remote_id;
p_m_remote_ref = b_port->p_m_remote_ref;
+ p_m_tx_gain = b_port->p_m_tx_gain;
+ p_m_rx_gain = b_port->p_m_rx_gain;
+ p_m_pipeline = b_port->p_m_pipeline;
+ p_m_crypt_key = b_port->p_m_crypt_key;
+ p_m_crypt_key_len = b_port->p_m_crypt_key_len;
+ p_m_crypt_key_type = /*b_port->p_m_crypt_key_type*/1;
}
switch(event)
if (p_m_remote_ref)
{
/* export bchannel */
- message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid);
+ message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
add_trace("type", NULL, "assign");
#ifdef SOCKET_MISDN
/* in case, the bchannel is exported right after seize_bchannel */
/* export bchannel */
/* p_m_remote_id is set, when this event happens. */
- message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid);
+ message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
add_trace("type", NULL, "assign");
#ifdef SOCKET_MISDN
* OR bchannel is not used anymore
* OR bchannel has been exported to an obsolete ref,
* so reimport, to later export to new remote */
- message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid);
+ message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
add_trace("type", NULL, "remove");
#ifdef SOCKET_MISDN
case B_STATE_REMOTE:
/* bchannel is exported, so we re-import */
- message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid);
+ message_bchannel_to_join(mISDNport->b_remote_id[i], 0, BCHANNEL_REMOVE, portid, 0,0,0,0,0,0);
chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
add_trace("type", NULL, "remove");
#ifdef SOCKET_MISDN
/* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
if (p_m_remote_ref)
{
- message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid);
+ message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
add_trace("type", NULL, "assign");
#ifdef SOCKET_MISDN
/* bchannel is now imported, but is requied by Port class, so we reactivate / export */
if (p_m_remote_ref)
{
- message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid);
+ message_bchannel_to_join(p_m_remote_id, p_m_remote_ref, BCHANNEL_ASSIGN, portid, p_m_tx_gain, p_m_rx_gain, p_m_pipeline, p_m_crypt_key, p_m_crypt_key_len, p_m_crypt_key_type);
chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
add_trace("type", NULL, "assign");
#ifdef SOCKET_MISDN
switch(param->mISDNsignal.message)
{
case mISDNSIGNAL_VOLUME:
- if (p_m_txvol != param->mISDNsignal.txvol)
+ if (p_m_tx_gain != param->mISDNsignal.tx_gain)
{
- p_m_txvol = param->mISDNsignal.txvol;
- PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_txvol);
+ p_m_tx_gain = param->mISDNsignal.tx_gain;
+ PDEBUG(DEBUG_BCHANNEL, "we change tx-volume to shift=%d.\n", p_m_tx_gain);
if (p_m_b_index >= 0)
if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
#ifdef SOCKET_MISDN
- ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], VOL_CHANGE_TX, p_m_txvol, "DSP-TXVOL", p_m_txvol);
+ ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], VOL_CHANGE_TX, p_m_tx_gain, "DSP-TX_GAIN", p_m_tx_gain);
#else
- ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_TX, p_m_txvol, "DSP-TXVOL", p_m_txvol);
+ ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_TX, p_m_tx_gain, "DSP-TX_GAIN", p_m_tx_gain);
#endif
} else
- PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rxvol);
- if (p_m_rxvol != param->mISDNsignal.rxvol)
+ PDEBUG(DEBUG_BCHANNEL, "we already have tx-volume shift=%d.\n", p_m_rx_gain);
+ if (p_m_rx_gain != param->mISDNsignal.rx_gain)
{
- p_m_rxvol = param->mISDNsignal.rxvol;
- PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rxvol);
+ p_m_rx_gain = param->mISDNsignal.rx_gain;
+ PDEBUG(DEBUG_BCHANNEL, "we change rx-volume to shift=%d.\n", p_m_rx_gain);
if (p_m_b_index >= 0)
if (p_m_mISDNport->b_state[p_m_b_index] == B_STATE_ACTIVE)
#ifdef SOCKET_MISDN
- ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], VOL_CHANGE_RX, p_m_rxvol, "DSP-RXVOL", p_m_rxvol);
+ ph_control(p_m_mISDNport, this, p_m_mISDNport->b_socket[p_m_b_index], VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain);
#else
- ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_RX, p_m_rxvol, "DSP-RXVOL", p_m_rxvol);
+ ph_control(p_m_mISDNport, this, p_m_mISDNport->b_addr[p_m_b_index], VOL_CHANGE_RX, p_m_rx_gain, "DSP-RX_GAIN", p_m_rx_gain);
#endif
} else
- PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rxvol);
+ PDEBUG(DEBUG_BCHANNEL, "we already have rx-volume shift=%d.\n", p_m_rx_gain);
break;
case mISDNSIGNAL_CONF:
void message_crypt(unsigned long epoint_id, int message_id, union parameter *param);
struct mISDNport *p_m_mISDNport; /* pointer to port */
int p_m_delay; /* use delay instead of dejitter */
- int p_m_txvol, p_m_rxvol; /* volume shift (0 = no change) */
+ int p_m_tx_gain, p_m_rx_gain; /* volume shift (0 = no change) */
char p_m_pipeline[256]; /* filter pipeline */
int p_m_echo, p_m_conf; /* remote echo, conference number */
int p_m_tone; /* current kernel space tone */
#define DEFAULT_ENDPOINT_APP EndpointAppPBX
-#define VERSION_STRING "0.4 (Spring 2007)"
+#define VERSION_STRING "0.5 (Spring 2007)"
extern int memuse;
extern int mmemuse;
struct param_mISDNsignal {
int message;
- int rxvol;
- int txvol;
+ int tx_gain;
+ int rx_gain;
int conf;
int joindata;
int tone;
struct param_bchannel {
int type; /* BCHANNEL_* */
unsigned long handle; /* bchannel stack/portid */
+ int tx_gain, rx_gain;
+ char pipeline[256];
+ unsigned char crypt[128];
+ int crypt_len;
+ int crypt_type; /* 1 = blowfish */
};
/* structure of message parameter */
{ ACTION_REPLY,
"reply", &EndpointAppPBX::action_init_redial_reply, &EndpointAppPBX::action_dialing_reply, NULL,
PARAM_CONNECT | PARAM_SELECT,
- "Caller replies. (last incomming call(s))"},
+ "Caller replies. (last incoming call(s))"},
{ ACTION_POWERDIAL,
"powerdial", NULL, &EndpointAppPBX::action_dialing_powerdial, NULL,
PARAM_CONNECT | PARAM_DELAY | PARAM_LIMIT | PARAM_TIMEOUT,
+doku: rx_vol -> rx_gain
+
+context
+doku: context
fuer asterisk: dejitter tx_buffer in dsp.o