LCR is now uses socket based mISDN V2 API
*** chan_lcr, the Asterisk interface works (not complete yet). -> LCR can be used as Asterisk channel driver. modified: Makefile modified: Makefile.am modified: README modified: action.cpp modified: apppbx.cpp modified: bchannel.c modified: bchannel.h modified: callerid.c modified: cause.c modified: chan_lcr.c modified: chan_lcr.h modified: configure.ac modified: default/routing.conf modified: dss1.cpp modified: dss1.h modified: genrc.c modified: ie.cpp modified: interface.c modified: lcradmin.c modified: mISDN.cpp modified: mISDN.h modified: main.c modified: main.h modified: message.h modified: myisdn.h modified: route.c modified: socket_server.c modified: trace.h
This commit is contained in:
parent
29506a890c
commit
026b04fc75
42
Makefile
42
Makefile
|
@ -10,19 +10,15 @@
|
|||
#*****************************************************************************/
|
||||
|
||||
WITH-CRYPTO = 42 # comment this out, if no libcrypto should be used
|
||||
#WITH-ASTERISK = 42 # comment this out, if you don't require built-in Asterisk channel driver.
|
||||
WITH-SOCKET = 42 # compile for socket based mISDN (this options is far unfinished !!!)
|
||||
WITH-ASTERISK = 42 # comment this out, if you don't require built-in Asterisk channel driver.
|
||||
# note: check your location and the names of libraries.
|
||||
|
||||
# select location to install
|
||||
INSTALL_BIN = /usr/local/bin
|
||||
INSTALL_CHAN = /usr/lib/asterisk/modules
|
||||
INSTALL_DATA = /usr/local/lcr
|
||||
|
||||
ifdef WITH-SOCKET
|
||||
LIBS += -lmisdn -lpthread
|
||||
else
|
||||
LIBS += -lisdnnet -lmISDN -lpthread
|
||||
endif
|
||||
CHANLIBS += -lmISDN
|
||||
|
||||
# give location of the curses or ncurses library
|
||||
|
@ -43,13 +39,11 @@ GENW = ./genwave
|
|||
GENRC = ./genrc
|
||||
GENEXT = ./genextension
|
||||
CFLAGS = -Wall -g -DINSTALL_DATA=\"$(INSTALL_DATA)\"
|
||||
CFLAGS += -I/usr/include/mISDNuser
|
||||
#CFLAGS = -Wall -g -DINSTALL_DATA=\"$(INSTALL_DATA)\"
|
||||
ifdef WITH-CRYPTO
|
||||
CFLAGS += -DCRYPTO
|
||||
endif
|
||||
ifdef WITH-SOCKET
|
||||
CFLAGS += -DSOCKET_MISDN -I/usr/include/mISDNuser
|
||||
endif
|
||||
ifdef WITH-CRYPTO
|
||||
LIBDIR += -L/usr/local/ssl/lib
|
||||
CFLAGS += -I/usr/local/ssl/include
|
||||
|
@ -63,12 +57,12 @@ endif
|
|||
# @exit
|
||||
|
||||
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'
|
||||
@sh -c 'grep -n strcpy *.c* --exclude chan_lcr.c --exclude bchannel.c --exclude callerid.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 --exclude callerid.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 --exclude callerid.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 --exclude callerid.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 --exclude callerid.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 --exclude callerid.c ; if test $$''? = 0 ; then echo "dont use snprintf, use makro instead." ; exit -1 ; fi'
|
||||
@echo "All LCR binaries done"
|
||||
@sync
|
||||
@exit
|
||||
|
@ -128,7 +122,9 @@ apppbx.o: apppbx.cpp *.h Makefile
|
|||
$(PP) -c $(CFLAGS) apppbx.cpp -o apppbx.o
|
||||
|
||||
callerid.o: callerid.c *.h Makefile
|
||||
$(PP) -c $(CFLAGS) callerid.c -o callerid.o
|
||||
$(CC) -c $(CFLAGS) callerid.c -o callerid.o
|
||||
callerid.ooo: callerid.c *.h Makefile
|
||||
$(PP) -c $(CFLAGS) callerid.c -o callerid.ooo
|
||||
|
||||
join.o: join.cpp *.h Makefile
|
||||
$(PP) -c $(CFLAGS) join.cpp -o join.o
|
||||
|
@ -187,7 +183,7 @@ $(LCR): main.o \
|
|||
endpoint.o \
|
||||
endpointapp.o \
|
||||
apppbx.o \
|
||||
callerid.o \
|
||||
callerid.ooo \
|
||||
crypt.o \
|
||||
action.o \
|
||||
action_vbox.o \
|
||||
|
@ -215,7 +211,7 @@ $(LCR): main.o \
|
|||
endpoint.o \
|
||||
endpointapp.o \
|
||||
apppbx.o \
|
||||
callerid.o \
|
||||
callerid.ooo \
|
||||
crypt.o \
|
||||
action.o \
|
||||
action_vbox.o \
|
||||
|
@ -232,8 +228,8 @@ $(LCRADMIN): lcradmin.c cause.c *.h Makefile
|
|||
$(PP) $(LIBDIR) $(CFLAGS_LCRADMIN) $(CURSES) -lm lcradmin.c cause.c \
|
||||
-o $(LCRADMIN)
|
||||
|
||||
$(CHAN_LCR): chan_lcr.o bchannel.o *.h Makefile
|
||||
gcc -shared -Xlinker -x $(LDFLAGS) -o $(CHAN_LCR) chan_lcr.o bchannel.o
|
||||
$(CHAN_LCR): chan_lcr.o bchannel.o callerid.o *.h Makefile
|
||||
$(CC) -shared -Xlinker -x $(LDFLAGS) -o $(CHAN_LCR) chan_lcr.o bchannel.o callerid.o
|
||||
|
||||
|
||||
$(LCRWATCH): watch.c *.h Makefile
|
||||
|
@ -264,9 +260,9 @@ install:
|
|||
-killall -9 -w -q lcr # the following error must be ignored
|
||||
cp $(LCR) $(INSTALL_BIN)
|
||||
cp $(LCRADMIN) $(INSTALL_BIN)
|
||||
#ifdef WITH-ASTERISK
|
||||
# cp $(CHAN_LCR) $(INSTALL_CHAN)
|
||||
#endif
|
||||
ifdef WITH-ASTERISK
|
||||
cp $(CHAN_LCR) $(INSTALL_CHAN)
|
||||
endif
|
||||
# cp $(LCRWATCH) $(INSTALL_BIN)
|
||||
cp $(GEN) $(INSTALL_BIN)
|
||||
cp $(GENW) $(INSTALL_BIN)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
OUTDATED!!!! must be rewritten! see Makefile
|
||||
|
||||
## Makefile.am -- Process this file with automake to produce Makefile.in
|
||||
|
||||
|
||||
|
|
10
README
10
README
|
@ -421,3 +421,13 @@ Changes in Version 0.5
|
|||
- Errors in information elements are now reported inside log/trace.
|
||||
- Recover bchannel (de-)activation if message from mISDN got lost
|
||||
|
||||
Changes in Version 1.0
|
||||
- Bugfixes
|
||||
- Complete port to new mISDN V2 API (socket based).
|
||||
-> Old mISDN will not work anymore.
|
||||
- Interfaces mode (NT/TE PTP/PTMP) can now be changed at runtime.
|
||||
-> No more module parameters must be given for cards.
|
||||
- First Alpha release of chan_lcr - the Asterisk PBX channel link driver.
|
||||
-> Use LCR in conjunction with Asterisk, or simply as ISDN frontend.
|
||||
|
||||
|
||||
|
|
132
action.cpp
132
action.cpp
|
@ -48,9 +48,9 @@ void EndpointAppPBX::_action_init_call(char *remote)
|
|||
trace_header("ACTION remote (not available)", DIRECTION_NONE);
|
||||
add_trace("application", NULL, "%s", remote);
|
||||
end_trace();
|
||||
message_disconnect_port(portlist, CAUSE_RESSOURCEUNAVAIL, LOCATION_PRIVATE_LOCAL, "");
|
||||
message_disconnect_port(portlist, CAUSE_OUTOFORDER, LOCATION_PRIVATE_LOCAL, "");
|
||||
new_state(EPOINT_STATE_OUT_DISCONNECT);
|
||||
set_tone(portlist,"cause_22");
|
||||
set_tone(portlist,"cause_1b");
|
||||
return;
|
||||
}
|
||||
join = new JoinRemote(ea_endpoint->ep_serial, remote, admin->sock);
|
||||
|
@ -67,57 +67,6 @@ void EndpointAppPBX::action_init_call(void)
|
|||
}
|
||||
void EndpointAppPBX::action_init_remote(void)
|
||||
{
|
||||
struct route_param *rparam;
|
||||
struct port_list *portlist = ea_endpoint->ep_portlist;
|
||||
struct lcr_msg *message;
|
||||
struct capa_info capainfo;
|
||||
struct caller_info callerinfo;
|
||||
struct redir_info redirinfo;
|
||||
struct dialing_info dialinginfo;
|
||||
char context[128] = "";
|
||||
char remote[32];
|
||||
|
||||
if (!(rparam = routeparam(e_action, PARAM_APPLICATION)))
|
||||
{
|
||||
trace_header("ACTION remote (no application given)", DIRECTION_NONE);
|
||||
end_trace();
|
||||
new_state(EPOINT_STATE_OUT_DISCONNECT);
|
||||
message_disconnect_port(portlist, CAUSE_SERVICEUNAVAIL, LOCATION_PRIVATE_LOCAL, "");
|
||||
set_tone(portlist, "cause_3f");
|
||||
return;
|
||||
}
|
||||
SCPY(remote, rparam->string_value);
|
||||
_action_init_call(remote);
|
||||
|
||||
/* create bearer/caller/dialinginfo */
|
||||
memcpy(&capainfo, &e_capainfo, sizeof(capainfo));
|
||||
memcpy(&callerinfo, &e_callerinfo, sizeof(callerinfo));
|
||||
memcpy(&redirinfo, &e_redirinfo, sizeof(redirinfo));
|
||||
memset(&dialinginfo, 0, sizeof(dialinginfo));
|
||||
|
||||
if ((rparam = routeparam(e_action, PARAM_CONTEXT)))
|
||||
{
|
||||
SCPY(context, rparam->string_value);
|
||||
}
|
||||
if ((rparam = routeparam(e_action, PARAM_EXTEN)))
|
||||
{
|
||||
SCPY(dialinginfo.id, rparam->string_value);
|
||||
dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
|
||||
}
|
||||
/* send setup to remote */
|
||||
trace_header("ACTION remote (setup)", DIRECTION_NONE);
|
||||
add_trace("number", NULL, dialinginfo.id);
|
||||
add_trace("remote", NULL, remote);
|
||||
if (context[0])
|
||||
add_trace("context", NULL, context);
|
||||
end_trace();
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_SETUP);
|
||||
memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info));
|
||||
memcpy(&message->param.setup.redirinfo, &redirinfo, sizeof(struct redir_info));
|
||||
memcpy(&message->param.setup.callerinfo, &callerinfo, sizeof(struct caller_info));
|
||||
memcpy(&message->param.setup.capainfo, &capainfo, sizeof(struct capa_info));
|
||||
SCPY(message->param.setup.context, context);
|
||||
message_put(message);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -399,22 +348,77 @@ void EndpointAppPBX::action_dialing_external(void)
|
|||
|
||||
void EndpointAppPBX::action_dialing_remote(void)
|
||||
{
|
||||
struct lcr_msg *message;
|
||||
struct dialing_info dialinginfo;
|
||||
// struct route_param *rparam;
|
||||
struct route_param *rparam;
|
||||
struct port_list *portlist = ea_endpoint->ep_portlist;
|
||||
struct lcr_msg *message;
|
||||
struct capa_info capainfo;
|
||||
struct caller_info callerinfo;
|
||||
struct redir_info redirinfo;
|
||||
struct dialing_info dialinginfo;
|
||||
char context[128] = "";
|
||||
char remote[32];
|
||||
|
||||
/* create bearer/caller/dialinginfo */
|
||||
memset(&dialinginfo, 0, sizeof(dialinginfo));
|
||||
|
||||
if (dialinginfo.id[0])
|
||||
if (e_state == EPOINT_STATE_IN_SETUP && !ea_endpoint->ep_join_id)
|
||||
{
|
||||
/* add or update outgoing call */
|
||||
trace_header("ACTION remote (dialing)", DIRECTION_NONE);
|
||||
/* no join yet, sending setup */
|
||||
if (!(rparam = routeparam(e_action, PARAM_APPLICATION)))
|
||||
{
|
||||
trace_header("ACTION remote (no application given)", DIRECTION_NONE);
|
||||
end_trace();
|
||||
new_state(EPOINT_STATE_OUT_DISCONNECT);
|
||||
message_disconnect_port(portlist, CAUSE_SERVICEUNAVAIL, LOCATION_PRIVATE_LOCAL, "");
|
||||
set_tone(portlist, "cause_3f");
|
||||
return;
|
||||
}
|
||||
SCPY(remote, rparam->string_value);
|
||||
_action_init_call(remote);
|
||||
|
||||
/* create bearer/caller/dialinginfo */
|
||||
memcpy(&capainfo, &e_capainfo, sizeof(capainfo));
|
||||
memcpy(&callerinfo, &e_callerinfo, sizeof(callerinfo));
|
||||
memcpy(&redirinfo, &e_redirinfo, sizeof(redirinfo));
|
||||
memset(&dialinginfo, 0, sizeof(dialinginfo));
|
||||
|
||||
if ((rparam = routeparam(e_action, PARAM_CONTEXT)))
|
||||
{
|
||||
SCPY(context, rparam->string_value);
|
||||
}
|
||||
if ((rparam = routeparam(e_action, PARAM_EXTEN)))
|
||||
{
|
||||
SCPY(dialinginfo.id, rparam->string_value);
|
||||
dialinginfo.ntype = INFO_NTYPE_UNKNOWN;
|
||||
} else
|
||||
{
|
||||
SCPY(dialinginfo.id, e_extdialing);
|
||||
}
|
||||
/* send setup to remote */
|
||||
trace_header("ACTION remote (setup)", DIRECTION_NONE);
|
||||
add_trace("number", NULL, dialinginfo.id);
|
||||
add_trace("remote", NULL, remote);
|
||||
if (context[0])
|
||||
add_trace("context", NULL, context);
|
||||
end_trace();
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_INFORMATION);
|
||||
memcpy(&message->param.information, &dialinginfo, sizeof(struct dialing_info));
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_SETUP);
|
||||
memcpy(&message->param.setup.dialinginfo, &dialinginfo, sizeof(struct dialing_info));
|
||||
memcpy(&message->param.setup.redirinfo, &redirinfo, sizeof(struct redir_info));
|
||||
memcpy(&message->param.setup.callerinfo, &callerinfo, sizeof(struct caller_info));
|
||||
memcpy(&message->param.setup.capainfo, &capainfo, sizeof(struct capa_info));
|
||||
SCPY(message->param.setup.context, context);
|
||||
message_put(message);
|
||||
} else
|
||||
{
|
||||
/* send overlap digits */
|
||||
trace_header("ACTION remote (dialing)", DIRECTION_NONE);
|
||||
add_trace("number", NULL, e_extdialing);
|
||||
end_trace();
|
||||
if (e_extdialing[0])
|
||||
{
|
||||
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_INFORMATION);
|
||||
memcpy(&message->param.information, &e_dialinginfo, sizeof(struct dialing_info));
|
||||
SCPY(message->param.information.id, e_extdialing);
|
||||
e_extdialing = e_dialinginfo.id + strlen(e_dialinginfo.id);
|
||||
message_put(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -621,7 +621,7 @@ foundif:
|
|||
if (!interface->ifport)
|
||||
{
|
||||
/* no ports */
|
||||
trace_header("CHANNEL SELECTION (interface has no active ports, skipping)", DIRECTION_NONE);
|
||||
trace_header("CHANNEL SELECTION (active ports, skipping)", DIRECTION_NONE);
|
||||
add_trace("interface", NULL, "%s", interface->name);
|
||||
end_trace();
|
||||
interface = interface->next;
|
||||
|
@ -672,7 +672,7 @@ foundif:
|
|||
/* see if link is up on PTP*/
|
||||
if (mISDNport->l2hold && !mISDNport->l2link)
|
||||
{
|
||||
trace_header("CHANNEL SELECTION (port holds layer 2, but layer 2 is down, skipping)", DIRECTION_NONE);
|
||||
trace_header("CHANNEL SELECTION (port's layer 2 is down, skipping)", DIRECTION_NONE);
|
||||
add_trace("port", NULL, "%d", ifport->portnum);
|
||||
add_trace("position", NULL, "%d", index);
|
||||
end_trace();
|
||||
|
@ -809,6 +809,11 @@ foundif:
|
|||
if (ifport != ifport_start)
|
||||
goto nextport;
|
||||
|
||||
if (!ifname) {
|
||||
interface = interface->next;
|
||||
goto checknext;
|
||||
}
|
||||
|
||||
return(NULL); /* no port found */
|
||||
}
|
||||
|
||||
|
|
407
bchannel.c
407
bchannel.c
|
@ -19,16 +19,11 @@
|
|||
#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 <mISDNif.h>
|
||||
#else
|
||||
#include <mISDNuser/isdn_net.h>
|
||||
#include <mISDNuser/net_l3.h>
|
||||
#endif
|
||||
|
||||
#include <asterisk/frame.h>
|
||||
|
||||
|
@ -52,9 +47,9 @@ enum {
|
|||
BSTATE_IDLE,
|
||||
BSTATE_ACTIVATING,
|
||||
BSTATE_ACTIVE,
|
||||
BSTATE_DEACTIVATING,
|
||||
};
|
||||
|
||||
#ifdef SOCKET_MISDN
|
||||
|
||||
int bchannel_initialize(void)
|
||||
{
|
||||
|
@ -64,90 +59,25 @@ int bchannel_initialize(void)
|
|||
void bchannel_deinitialize(void)
|
||||
{
|
||||
}
|
||||
#else
|
||||
int bchannel_entity = 0; /* used for udevice */
|
||||
int bchannel_device = -1; /* the device handler and port list */
|
||||
|
||||
int bchannel_initialize(void)
|
||||
{
|
||||
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)
|
||||
{
|
||||
CERROR(NULL, NULL, "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;
|
||||
CDEBUG(NULL, NULL, "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:
|
||||
CERROR(NULL, NULL, "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 = (unsigned long *)(buffer+MISDN_HEADER_LEN);
|
||||
int ret;
|
||||
|
||||
CDEBUG(NULL, NULL, "Sending PH_CONTROL %d,%d\n", c1, c2);
|
||||
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)
|
||||
if (ret < 0)
|
||||
CERROR(NULL, NULL, "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)
|
||||
|
@ -160,32 +90,19 @@ static void ph_control(unsigned long handle, unsigned long c1, unsigned long c2,
|
|||
|
||||
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 = (unsigned long *)(buffer+MISDN_HEADER_LEN);
|
||||
int ret;
|
||||
|
||||
CDEBUG(NULL, NULL, "Sending PH_CONTROL (block) %d\n", c1);
|
||||
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)
|
||||
if (ret < 0)
|
||||
CERROR(NULL, NULL, "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);
|
||||
|
@ -200,7 +117,6 @@ static void ph_control_block(unsigned long handle, unsigned long c1, void *c2, i
|
|||
int bchannel_create(struct bchannel *bchannel)
|
||||
{
|
||||
int ret;
|
||||
#ifdef SOCKET_MISDN
|
||||
unsigned long on = 1;
|
||||
struct sockaddr_mISDN addr;
|
||||
|
||||
|
@ -225,6 +141,7 @@ int bchannel_create(struct bchannel *bchannel)
|
|||
CERROR(NULL, NULL, "Failed to set bchannel-socket handle 0x%x into nonblocking IO\n", bchannel->handle);
|
||||
close(bchannel->b_sock);
|
||||
bchannel->b_sock = -1;
|
||||
bchannel->handle = 0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -249,86 +166,6 @@ int bchannel_create(struct bchannel *bchannel)
|
|||
#endif
|
||||
return(1);
|
||||
}
|
||||
#else
|
||||
unsigned char buff[1024];
|
||||
layer_info_t li;
|
||||
mISDN_pid_t pid;
|
||||
|
||||
if (bchannel->b_stid)
|
||||
{
|
||||
CERROR(NULL, NULL, "Stack already created for address 0x%lx\n", bchannel->b_stid);
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (bchannel->b_addr)
|
||||
{
|
||||
CERROR(NULL, NULL, "Stack already created for address 0x%lx\n", bchannel->b_addr);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* create new layer */
|
||||
CDEBUG(NULL, NULL, "creating new layer for stid 0x%lx.\n" , bchannel->handle);
|
||||
memset(&li, 0, sizeof(li));
|
||||
memset(&pid, 0, sizeof(pid));
|
||||
li.object_id = -1;
|
||||
li.extentions = 0;
|
||||
li.st = bchannel->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:
|
||||
CERROR(NULL, NULL, "mISDN_new_layer() failed to add bchannel for stid 0x%lx.\n", bchannel->handle);
|
||||
goto failed;
|
||||
}
|
||||
if (!li.id)
|
||||
{
|
||||
goto failed_new_layer;
|
||||
}
|
||||
bchannel->b_stid = bchannel->handle;
|
||||
bchannel->b_addr = li.id;
|
||||
CDEBUG(NULL, NULL, "new layer (b_addr=0x%x)\n", bchannel->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, bchannel->b_stid, &pid);
|
||||
if (ret)
|
||||
{
|
||||
stack_error:
|
||||
CERROR(NULL, NULL, "mISDN_set_stack() failed (ret=%d) to add bchannel stid=0x%lx\n", ret, bchannel->b_stid);
|
||||
mISDN_write_frame(bchannel_device, buff, bchannel->b_addr, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
|
||||
goto failed;
|
||||
}
|
||||
ret = mISDN_get_setstack_ind(bchannel_device, bchannel->b_addr);
|
||||
if (ret)
|
||||
goto stack_error;
|
||||
|
||||
/* get layer id */
|
||||
bchannel->b_addr = mISDN_get_layerid(bchannel_device, bchannel->b_stid, 4);
|
||||
if (!bchannel->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
|
||||
|
||||
return(1);
|
||||
|
||||
failed:
|
||||
bchannel->b_stid = 0;
|
||||
bchannel->b_addr = 0;
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
@ -336,27 +173,18 @@ failed:
|
|||
*/
|
||||
void bchannel_activate(struct bchannel *bchannel, int activate)
|
||||
{
|
||||
#ifdef SOCKET_MISDN
|
||||
struct mISDNhead act;
|
||||
int ret;
|
||||
|
||||
/* activate bchannel */
|
||||
CDEBUG(NULL, NULL, "%sActivating B-channel.\n", activate?"":"De-");
|
||||
act.prim = (activate)?DL_ESTABLISH_REQ:DL_RELEASE_REQ;
|
||||
act.id = 0;
|
||||
ret = sendto(bchannel->b_sock, &act, MISDN_HEADER_LEN, 0, NULL, 0);
|
||||
if (!ret)
|
||||
if (ret < 0)
|
||||
CERROR(NULL, NULL, "Failed to send to socket %d\n", bchannel->b_sock);
|
||||
#else
|
||||
iframe_t act;
|
||||
|
||||
/* activate bchannel */
|
||||
act.prim = (activate?DL_ESTABLISH:DL_RELEASE) | REQUEST;
|
||||
act.addr = bchannel->b_addr | FLG_MSG_DOWN;
|
||||
act.dinfo = 0;
|
||||
act.len = 0;
|
||||
mISDN_write(bchannel_device, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
|
||||
#endif
|
||||
|
||||
bchannel->b_state = BSTATE_ACTIVATING;
|
||||
bchannel->b_state = (activate)?BSTATE_ACTIVATING:BSTATE_DEACTIVATING;
|
||||
#if 0
|
||||
/* trace */
|
||||
chan_trace_header(mISDNport, mISDNport->b_port[i], activate?(char*)"BCHANNEL activate":(char*)"BCHANNEL deactivate", DIRECTION_OUT);
|
||||
|
@ -371,15 +199,9 @@ void bchannel_activate(struct bchannel *bchannel, int activate)
|
|||
*/
|
||||
static void bchannel_activated(struct bchannel *bchannel)
|
||||
{
|
||||
#ifdef SOCKET_MISDN
|
||||
int handle;
|
||||
|
||||
handle = bchannel->b_sock;
|
||||
#else
|
||||
unsigned long handle;
|
||||
|
||||
handle = bchannel->b_addr;
|
||||
#endif
|
||||
|
||||
/* set dsp features */
|
||||
if (bchannel->b_txdata)
|
||||
|
@ -393,11 +215,7 @@ static void bchannel_activated(struct bchannel *bchannel)
|
|||
if (bchannel->b_rx_gain)
|
||||
ph_control(handle, DSP_VOL_CHANGE_RX, bchannel->b_rx_gain, "DSP-RX_GAIN", bchannel->b_rx_gain);
|
||||
if (bchannel->b_pipeline[0])
|
||||
#ifdef SOCKET_MISDN
|
||||
ph_control_block(handle, DSP_PIPELINE_CFG, bchannel->b_pipeline, strlen(bchannel->b_pipeline)+1, "DSP-PIPELINE", 0);
|
||||
#else
|
||||
ph_control_block(handle, PIPELINE_CFG, bchannel->b_pipeline, strlen(bchannel->b_pipeline)+1, "DSP-PIPELINE", 0);
|
||||
#endif
|
||||
if (bchannel->b_conf)
|
||||
ph_control(handle, DSP_CONF_JOIN, bchannel->b_conf, "DSP-CONF", bchannel->b_conf);
|
||||
if (bchannel->b_echo)
|
||||
|
@ -423,7 +241,6 @@ static void bchannel_activated(struct bchannel *bchannel)
|
|||
*/
|
||||
static void bchannel_destroy(struct bchannel *bchannel)
|
||||
{
|
||||
#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));
|
||||
|
@ -435,26 +252,6 @@ static void bchannel_destroy(struct bchannel *bchannel)
|
|||
close(bchannel->b_sock);
|
||||
bchannel->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 (bchannel->b_addr)
|
||||
{
|
||||
CDEBUG(NULL, NULL, "free stack (b_addr=0x%x)\n", bchannel->b_addr);
|
||||
mISDN_clear_stack(bchannel_device, bchannel->b_stid);
|
||||
mISDN_write_frame(bchannel_device, buff, bchannel->b_addr | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
|
||||
bchannel->b_stid = 0;
|
||||
bchannel->b_addr = 0;
|
||||
}
|
||||
#endif
|
||||
bchannel->b_state = BSTATE_IDLE;
|
||||
}
|
||||
|
||||
|
@ -470,11 +267,7 @@ static void bchannel_receive(struct bchannel *bchannel, unsigned long prim, unsi
|
|||
// unsigned char *p;
|
||||
// int l;
|
||||
|
||||
#ifdef SOCKET_MISDN
|
||||
if (prim == PH_CONTROL_IND)
|
||||
#else
|
||||
if (prim == (PH_CONTROL | INDICATION))
|
||||
#endif
|
||||
{
|
||||
if (len < 4)
|
||||
{
|
||||
|
@ -494,11 +287,7 @@ static void bchannel_receive(struct bchannel *bchannel, unsigned long prim, unsi
|
|||
}
|
||||
switch(cont)
|
||||
{
|
||||
#ifdef SOCKET_MISDN
|
||||
case DSP_BF_REJECT:
|
||||
#else
|
||||
case BF_REJECT:
|
||||
#endif
|
||||
#if 0
|
||||
chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
|
||||
add_trace("DSP-CRYPT", NULL, "error");
|
||||
|
@ -506,11 +295,7 @@ static void bchannel_receive(struct bchannel *bchannel, unsigned long prim, unsi
|
|||
#endif
|
||||
break;
|
||||
|
||||
#ifdef SOCKET_MISDN
|
||||
case DSP_BF_ACCEPT:
|
||||
#else
|
||||
case BF_ACCEPT:
|
||||
#endif
|
||||
#if 0
|
||||
chan_trace_header(p_m_mISDNport, this, "BCHANNEL control", DIRECTION_IN);
|
||||
add_trace("DSP-CRYPT", NULL, "ok");
|
||||
|
@ -529,7 +314,6 @@ static void bchannel_receive(struct bchannel *bchannel, unsigned long prim, unsi
|
|||
}
|
||||
return;
|
||||
}
|
||||
#ifdef SOCKET_MISDN
|
||||
if (prim == PH_DATA_REQ)
|
||||
{
|
||||
if (!bchannel->b_txdata)
|
||||
|
@ -540,32 +324,6 @@ static void bchannel_receive(struct bchannel *bchannel, unsigned long prim, unsi
|
|||
}
|
||||
return;
|
||||
}
|
||||
#else
|
||||
if (prim == (PH_SIGNAL | INDICATION))
|
||||
{
|
||||
switch(dinfo)
|
||||
{
|
||||
case CMX_TX_DATA:
|
||||
if (!bchannel->b_txdata)
|
||||
{
|
||||
/* if tx is off, it may happen that fifos send us pending informations, we just ignore them */
|
||||
CDEBUG(NULL, NULL, "ignoring tx data, because 'txdata' is turned off\n");
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
if (prim != PH_DATA_IND && prim != DL_DATA_IND)
|
||||
{
|
||||
CERROR(NULL, NULL, "Bchannel received unknown primitve: 0x%lx\n", prim);
|
||||
|
@ -592,11 +350,16 @@ static void bchannel_receive(struct bchannel *bchannel, unsigned long prim, unsi
|
|||
/* return, because we have no audio from port */
|
||||
return;
|
||||
}
|
||||
len = write(bchannel->call->pipe[1], data, len);
|
||||
if (len < 0)
|
||||
if (bchannel->call->pipe[1] > -1)
|
||||
{
|
||||
CDEBUG(NULL, NULL, "broken pipe on bchannel pipe\n");
|
||||
return;
|
||||
len = write(bchannel->call->pipe[1], data, len);
|
||||
if (len < 0)
|
||||
{
|
||||
close(bchannel->call->pipe[1]);
|
||||
bchannel->call->pipe[1] = -1;
|
||||
CDEBUG(NULL, NULL, "broken pipe on bchannel pipe\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -606,30 +369,22 @@ static void bchannel_receive(struct bchannel *bchannel, unsigned long prim, unsi
|
|||
*/
|
||||
void bchannel_transmit(struct bchannel *bchannel, unsigned char *data, int len)
|
||||
{
|
||||
unsigned char buff[1025];
|
||||
#ifdef SOCKET_MISDN
|
||||
unsigned char buff[1024 + MISDN_HEADER_LEN], *p = buff + MISDN_HEADER_LEN;
|
||||
struct mISDNhead *frm = (struct mISDNhead *)buff;
|
||||
#else
|
||||
iframe_t *frm = (iframe_t *)buff;
|
||||
#endif
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
if (bchannel->b_state != BSTATE_ACTIVE)
|
||||
return;
|
||||
#ifdef SOCKET_MISDN
|
||||
if (len > 1024 || len < 1)
|
||||
return;
|
||||
for (i = 0; i < len; i++)
|
||||
*p++ = flip_bits[*data++];
|
||||
frm->prim = DL_DATA_REQ;
|
||||
frm->id = 0;
|
||||
ret = sendto(bchannel->b_sock, data, len, 0, NULL, 0);
|
||||
if (!ret)
|
||||
ret = sendto(bchannel->b_sock, buff, MISDN_HEADER_LEN+len, 0, NULL, 0);
|
||||
if (ret < 0)
|
||||
CERROR(NULL, NULL, "Failed to send to socket %d\n", bchannel->b_sock);
|
||||
#else
|
||||
frm->prim = DL_DATA | REQUEST;
|
||||
frm->addr = bchannel->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
|
||||
}
|
||||
|
||||
|
||||
|
@ -638,15 +393,9 @@ void bchannel_transmit(struct bchannel *bchannel, unsigned char *data, int len)
|
|||
*/
|
||||
void bchannel_join(struct bchannel *bchannel, unsigned short id)
|
||||
{
|
||||
#ifdef SOCKET_MISDN
|
||||
int handle;
|
||||
|
||||
handle = bchannel->b_sock;
|
||||
#else
|
||||
unsigned long handle;
|
||||
|
||||
handle = bchannel->b_addr;
|
||||
#endif
|
||||
if (id) {
|
||||
bchannel->b_conf = (id<<16) + bchannel_pid;
|
||||
bchannel->b_rxoff = 1;
|
||||
|
@ -665,7 +414,6 @@ void bchannel_join(struct bchannel *bchannel, unsigned short id)
|
|||
/*
|
||||
* main loop for processing messages from mISDN
|
||||
*/
|
||||
#ifdef SOCKET_MISDN
|
||||
int bchannel_handle(void)
|
||||
{
|
||||
int ret, work = 0;
|
||||
|
@ -681,7 +429,7 @@ int bchannel_handle(void)
|
|||
if (bchannel->b_sock > -1)
|
||||
{
|
||||
ret = recv(bchannel->b_sock, buffer, sizeof(buffer), 0);
|
||||
if (ret >= MISDN_HEADER_LEN)
|
||||
if (ret >= (int)MISDN_HEADER_LEN)
|
||||
{
|
||||
work = 1;
|
||||
switch(hh->prim)
|
||||
|
@ -729,99 +477,6 @@ int bchannel_handle(void)
|
|||
/* if we received at least one b-frame, we will return 1 */
|
||||
return(work);
|
||||
}
|
||||
#else
|
||||
int bchannel_handle(void)
|
||||
{
|
||||
struct bchannel *bchannel;
|
||||
iframe_t *frm;
|
||||
unsigned char buffer[2048];
|
||||
int len;
|
||||
|
||||
/* no device, no read */
|
||||
if (bchannel_device < 0)
|
||||
return(0);
|
||||
|
||||
/* get message from kernel */
|
||||
len = mISDN_read(bchannel_device, buffer, sizeof(buffer), 0);
|
||||
if (len < 0)
|
||||
{
|
||||
if (errno == EAGAIN)
|
||||
return(0);
|
||||
CERROR(NULL, NULL, "Failed to do mISDN_read()\n");
|
||||
return(0);
|
||||
}
|
||||
if (!len)
|
||||
{
|
||||
// printf("%s: ERROR: mISDN_read() returns nothing\n");
|
||||
return(0);
|
||||
}
|
||||
frm = (iframe_t *)buffer;
|
||||
|
||||
/* 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:
|
||||
return(1);
|
||||
}
|
||||
|
||||
/* find the mISDNport that belongs to the stack */
|
||||
bchannel = bchannel_first;
|
||||
while(bchannel)
|
||||
{
|
||||
if (frm->addr == bchannel->b_addr)
|
||||
break;
|
||||
bchannel = bchannel->next;
|
||||
}
|
||||
if (!bchannel)
|
||||
{
|
||||
CERROR(NULL, NULL, "message belongs to no bchannel: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, 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(bchannel, frm->prim, frm->dinfo, (unsigned char *)frm->data.p, frm->len);
|
||||
break;
|
||||
|
||||
case PH_ACTIVATE | INDICATION:
|
||||
case DL_ESTABLISH | INDICATION:
|
||||
case PH_ACTIVATE | CONFIRM:
|
||||
case DL_ESTABLISH | CONFIRM:
|
||||
CDEBUG(NULL, NULL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
|
||||
bchannel_activated(bchannel);
|
||||
break;
|
||||
|
||||
case PH_DEACTIVATE | INDICATION:
|
||||
case DL_RELEASE | INDICATION:
|
||||
case PH_DEACTIVATE | CONFIRM:
|
||||
case DL_RELEASE | CONFIRM:
|
||||
CDEBUG(NULL, NULL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
|
||||
// bchannel_deactivated(bchannel);
|
||||
break;
|
||||
|
||||
default:
|
||||
CERROR(NULL, NULL, "message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, len);
|
||||
}
|
||||
|
||||
out:
|
||||
return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
@ -863,7 +518,7 @@ struct bchannel *alloc_bchannel(unsigned long handle)
|
|||
while(*bchannelp)
|
||||
bchannelp = &((*bchannelp)->next);
|
||||
|
||||
*bchannelp = (struct bchannel *)malloc(sizeof(struct bchannel));
|
||||
*bchannelp = (struct bchannel *)calloc(1, sizeof(struct bchannel));
|
||||
if (!*bchannelp)
|
||||
return(NULL);
|
||||
(*bchannelp)->handle = handle;
|
||||
|
@ -881,11 +536,7 @@ void free_bchannel(struct bchannel *bchannel)
|
|||
if (*temp == bchannel)
|
||||
{
|
||||
*temp = (*temp)->next;
|
||||
#ifdef SOCKET_MISDN
|
||||
if (bchannel->b_sock > -1)
|
||||
#else
|
||||
if (bchannel->b_stid)
|
||||
#endif
|
||||
bchannel_destroy(bchannel);
|
||||
if (bchannel->call)
|
||||
{
|
||||
|
|
|
@ -14,12 +14,7 @@ struct bchannel {
|
|||
struct bchannel *next;
|
||||
struct chan_call *call; /* 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;
|
||||
|
|
20
callerid.c
20
callerid.c
|
@ -9,19 +9,23 @@
|
|||
** **
|
||||
\*****************************************************************************/
|
||||
|
||||
#include "main.h"
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "extension.h"
|
||||
#include "message.h"
|
||||
#include "callerid.h"
|
||||
|
||||
/* create caller id from digits by comparing with national and international
|
||||
* prefixes.
|
||||
*/
|
||||
char *nationalize_callerinfo(char *string, int *ntype, char *national, char *international)
|
||||
{
|
||||
if (!strncmp(options.international, string, strlen(options.international)))
|
||||
if (!strncmp(international, string, strlen(international)))
|
||||
{
|
||||
*ntype = INFO_NTYPE_INTERNATIONAL;
|
||||
return(string+strlen(international));
|
||||
}
|
||||
if (!strncmp(options.national, string, strlen(options.national)))
|
||||
if (!strncmp(national, string, strlen(national)))
|
||||
{
|
||||
*ntype = INFO_NTYPE_NATIONAL;
|
||||
return(string+strlen(national));
|
||||
|
@ -40,14 +44,16 @@ char *numberrize_callerinfo(char *string, int ntype, char *national, char *inter
|
|||
switch(ntype)
|
||||
{
|
||||
case INFO_NTYPE_INTERNATIONAL:
|
||||
UCPY(result, international);
|
||||
SCAT(result, string);
|
||||
strcpy(result, international);
|
||||
strncat(result, string, sizeof(result));
|
||||
result[sizeof(result)-1] = '\0';
|
||||
return(result);
|
||||
break;
|
||||
|
||||
case INFO_NTYPE_NATIONAL:
|
||||
UCPY(result, national);
|
||||
SCAT(result, string);
|
||||
strcpy(result, national);
|
||||
strncat(result, string, sizeof(result));
|
||||
result[sizeof(result)-1] = '\0';
|
||||
return(result);
|
||||
break;
|
||||
|
||||
|
|
8
cause.c
8
cause.c
|
@ -9,7 +9,13 @@
|
|||
** **
|
||||
\*****************************************************************************/
|
||||
|
||||
#include "main.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "macro.h"
|
||||
#include "cause.h"
|
||||
#include "extension.h"
|
||||
|
||||
struct isdn_cause isdn_cause[128] = {
|
||||
/********************************* - **/ /*38*/
|
||||
|
|
425
chan_lcr.c
425
chan_lcr.c
|
@ -86,6 +86,7 @@ If the ref is 0 and the state is CHAN_LCR_STATE_RELEASE, see the proceedure
|
|||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
//#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
@ -116,15 +117,16 @@ If the ref is 0 and the state is CHAN_LCR_STATE_RELEASE, see the proceedure
|
|||
|
||||
#include "extension.h"
|
||||
#include "message.h"
|
||||
#include "callerid.h"
|
||||
#include "lcrsocket.h"
|
||||
#include "cause.h"
|
||||
#include "bchannel.h"
|
||||
#include "chan_lcr.h"
|
||||
#include "callerid.h"
|
||||
|
||||
CHAN_LCR_STATE // state description structure
|
||||
MESSAGES // message text
|
||||
|
||||
u_char flip_bits[256];
|
||||
unsigned char flip_bits[256];
|
||||
|
||||
int lcr_debug=1;
|
||||
int mISDN_created=1;
|
||||
|
@ -142,7 +144,7 @@ int lcr_sock = -1;
|
|||
|
||||
struct admin_list {
|
||||
struct admin_list *next;
|
||||
struct admin_msg msg;
|
||||
struct admin_message msg;
|
||||
} *admin_first = NULL;
|
||||
|
||||
static struct ast_channel_tech lcr_tech;
|
||||
|
@ -150,7 +152,7 @@ static struct ast_channel_tech lcr_tech;
|
|||
/*
|
||||
* logging
|
||||
*/
|
||||
void chan_lcr_log(int type, const char *file, int line, struct chan_call *call, struct ast_channel *ast, const char *fmt, ...)
|
||||
void chan_lcr_log(int type, const char *file, int line, const char *function, struct chan_call *call, struct ast_channel *ast, const char *fmt, ...)
|
||||
{
|
||||
char buffer[1024];
|
||||
char call_text[128] = "NULL";
|
||||
|
@ -170,7 +172,7 @@ void chan_lcr_log(int type, const char *file, int line, struct chan_call *call,
|
|||
strncpy(ast_text, ast->name, sizeof(ast_text)-1);
|
||||
ast_text[sizeof(ast_text)-1] = '\0';
|
||||
|
||||
ast_log(type, file, line, "[call=%s ast=%s] %s", call_text, ast_text, buffer);
|
||||
ast_log(type, file, line, function, "[call=%s ast=%s] %s", call_text, ast_text, buffer);
|
||||
|
||||
ast_mutex_unlock(&log_lock);
|
||||
}
|
||||
|
@ -230,9 +232,9 @@ void free_call(struct chan_call *call)
|
|||
if (*temp == call)
|
||||
{
|
||||
*temp = (*temp)->next;
|
||||
if (call->pipe[0])
|
||||
if (call->pipe[0] > -1)
|
||||
close(call->pipe[0]);
|
||||
if (call->pipe[1])
|
||||
if (call->pipe[1] > -1)
|
||||
close(call->pipe[1]);
|
||||
if (call->bchannel)
|
||||
{
|
||||
|
@ -262,7 +264,7 @@ struct chan_call *alloc_call(void)
|
|||
while(*callp)
|
||||
callp = &((*callp)->next);
|
||||
|
||||
*callp = (struct chan_call *)malloc(sizeof(struct chan_call));
|
||||
*callp = (struct chan_call *)calloc(1, sizeof(struct chan_call));
|
||||
if (*callp)
|
||||
memset(*callp, 0, sizeof(struct chan_call));
|
||||
if (pipe((*callp)->pipe) < 0) {
|
||||
|
@ -310,17 +312,22 @@ int send_message(int message_type, unsigned long ref, union parameter *param)
|
|||
CDEBUG(NULL, NULL, "Ignoring message %d, because socket is closed.\n", message_type);
|
||||
return -1;
|
||||
}
|
||||
CDEBUG(NULL, NULL, "Sending message %d to socket.\n", message_type);
|
||||
CDEBUG(NULL, NULL, "Sending %s to socket.\n", messages_txt[message_type]);
|
||||
|
||||
adminp = &admin_first;
|
||||
while(*adminp)
|
||||
adminp = &((*adminp)->next);
|
||||
admin = (struct admin_list *)malloc(sizeof(struct admin_list));
|
||||
admin = (struct admin_list *)calloc(1, sizeof(struct admin_list));
|
||||
if (!admin) {
|
||||
CERROR(NULL, NULL, "No memory for message to LCR.\n");
|
||||
return -1;
|
||||
}
|
||||
*adminp = admin;
|
||||
|
||||
admin->msg.type = message_type;
|
||||
admin->msg.ref = ref;
|
||||
memcpy(&admin->msg.param, param, sizeof(union parameter));
|
||||
admin->msg.message = ADMIN_MESSAGE;
|
||||
admin->msg.u.msg.type = message_type;
|
||||
admin->msg.u.msg.ref = ref;
|
||||
memcpy(&admin->msg.u.msg.param, param, sizeof(union parameter));
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
@ -341,8 +348,9 @@ static void send_setup_to_lcr(struct chan_call *call)
|
|||
|
||||
/* send setup message to LCR */
|
||||
memset(&newparam, 0, sizeof(union parameter));
|
||||
strncpy(newparam.setup.dialinginfo.id, ast->exten, sizeof(newparam.setup.dialinginfo.id)-1);
|
||||
newparam.setup.callerinfo.itype = INFO_ITYPE_CHAN;
|
||||
newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
|
||||
newparam.setup.callerinfo.ntype = INFO_NTYPE_UNKNOWN;
|
||||
if (ast->cid.cid_num) if (ast->cid.cid_num[0])
|
||||
strncpy(newparam.setup.callerinfo.id, ast->cid.cid_num, sizeof(newparam.setup.callerinfo.id)-1);
|
||||
if (ast->cid.cid_name) if (ast->cid.cid_name[0])
|
||||
|
@ -404,10 +412,10 @@ static void send_dialque_to_lcr(struct chan_call *call)
|
|||
{
|
||||
union parameter newparam;
|
||||
|
||||
if (!call->ast || !call->ref || !call->dialque)
|
||||
if (!call->ast || !call->ref || !call->dialque[0])
|
||||
return;
|
||||
|
||||
CDEBUG(call, call->ast, "Sending dial queue to LCR.\n");
|
||||
CDEBUG(call, call->ast, "Sending dial queue to LCR. (dialing=%s)\n", call->dialque);
|
||||
|
||||
/* send setup message to LCR */
|
||||
memset(&newparam, 0, sizeof(union parameter));
|
||||
|
@ -429,6 +437,27 @@ static void bridge_message_if_bridged(struct chan_call *call, int message_type,
|
|||
send_message(message_type, call->bridge_call->ref, param);
|
||||
}
|
||||
|
||||
/*
|
||||
* send release message to LCR and import bchannel if exported
|
||||
*/
|
||||
static void send_release_and_import(struct chan_call *call, int cause, int location)
|
||||
{
|
||||
union parameter newparam;
|
||||
|
||||
/* importing channel */
|
||||
if (call->bchannel && call->bchannel->handle) {
|
||||
memset(&newparam, 0, sizeof(union parameter));
|
||||
newparam.bchannel.type = BCHANNEL_RELEASE;
|
||||
newparam.bchannel.handle = call->bchannel->handle;
|
||||
send_message(MESSAGE_BCHANNEL, call->ref, &newparam);
|
||||
}
|
||||
/* sending release */
|
||||
memset(&newparam, 0, sizeof(union parameter));
|
||||
newparam.disconnectinfo.cause = cause;
|
||||
newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
|
||||
send_message(MESSAGE_RELEASE, call->ref, &newparam);
|
||||
}
|
||||
|
||||
/*
|
||||
* check if extension matches and start asterisk
|
||||
* if it can match, proceed
|
||||
|
@ -439,6 +468,8 @@ static void lcr_start_pbx(struct chan_call *call, struct ast_channel *ast, int c
|
|||
int cause, ret;
|
||||
union parameter newparam;
|
||||
|
||||
CDEBUG(call, ast, "Try to start pbx. (exten=%s context=%s complete=%s)\n", ast->exten, ast->context, complete?"yes":"no");
|
||||
|
||||
if (complete)
|
||||
{
|
||||
/* if not match */
|
||||
|
@ -468,8 +499,10 @@ static void lcr_start_pbx(struct chan_call *call, struct ast_channel *ast, int c
|
|||
if (ast_canmatch_extension(ast, ast->context, ast->exten, 1, call->oad))
|
||||
{
|
||||
/* send setup acknowledge to lcr */
|
||||
memset(&newparam, 0, sizeof(union parameter));
|
||||
send_message(MESSAGE_OVERLAP, call->ref, &newparam);
|
||||
if (call->state != CHAN_LCR_STATE_IN_DIALING) {
|
||||
memset(&newparam, 0, sizeof(union parameter));
|
||||
send_message(MESSAGE_OVERLAP, call->ref, &newparam);
|
||||
}
|
||||
|
||||
/* change state */
|
||||
call->state = CHAN_LCR_STATE_IN_DIALING;
|
||||
|
@ -490,10 +523,7 @@ static void lcr_start_pbx(struct chan_call *call, struct ast_channel *ast, int c
|
|||
release:
|
||||
/* release lcr */
|
||||
CDEBUG(call, ast, "Releasing due to extension missmatch.\n");
|
||||
memset(&newparam, 0, sizeof(union parameter));
|
||||
newparam.disconnectinfo.cause = cause;
|
||||
newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
|
||||
send_message(MESSAGE_RELEASE, call->ref, &newparam);
|
||||
send_release_and_import(call, cause, LOCATION_PRIVATE_LOCAL);
|
||||
call->ref = 0;
|
||||
/* release asterisk */
|
||||
ast->hangupcause = call->cause;
|
||||
|
@ -521,9 +551,8 @@ static void lcr_start_pbx(struct chan_call *call, struct ast_channel *ast, int c
|
|||
static void lcr_in_setup(struct chan_call *call, int message_type, union parameter *param)
|
||||
{
|
||||
struct ast_channel *ast;
|
||||
union parameter newparam;
|
||||
|
||||
CDEBUG(call, NULL, "Incomming setup from LCR. (callerid %d, dialing %d)\n", param->setup.callerinfo.id, param->setup.dialinginfo.id);
|
||||
CDEBUG(call, NULL, "Incomming setup from LCR. (callerid %s, dialing %s)\n", param->setup.callerinfo.id, param->setup.dialinginfo.id);
|
||||
|
||||
/* create asterisk channel instrance */
|
||||
ast = ast_channel_alloc(1, AST_STATE_RESERVED, NULL, NULL, "", NULL, "", 0, "%s/%d", lcr_type, ++glob_channel);
|
||||
|
@ -531,15 +560,12 @@ static void lcr_in_setup(struct chan_call *call, int message_type, union paramet
|
|||
{
|
||||
/* release */
|
||||
CERROR(call, NULL, "Failed to create Asterisk channel - releasing.\n");
|
||||
memset(&newparam, 0, sizeof(union parameter));
|
||||
newparam.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL;
|
||||
newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
|
||||
send_message(MESSAGE_RELEASE, call->ref, &newparam);
|
||||
send_release_and_import(call, CAUSE_RESSOURCEUNAVAIL, LOCATION_PRIVATE_LOCAL);
|
||||
/* remove call */
|
||||
free_call(call);
|
||||
return;
|
||||
}
|
||||
/* set ast pointer */
|
||||
/* link together */
|
||||
call->ast = ast;
|
||||
ast->tech_pvt = call;
|
||||
ast->tech = &lcr_tech;
|
||||
|
@ -550,6 +576,8 @@ static void lcr_in_setup(struct chan_call *call, int message_type, union paramet
|
|||
strncpy(ast->exten, param->setup.dialinginfo.id, AST_MAX_EXTENSION-1);
|
||||
if (param->setup.context[0])
|
||||
strncpy(ast->context, param->setup.context, AST_MAX_CONTEXT-1);
|
||||
else
|
||||
strncpy(ast->context, param->setup.callerinfo.interface, AST_MAX_CONTEXT-1);
|
||||
if (param->setup.callerinfo.id[0])
|
||||
ast->cid.cid_num = strdup(param->setup.callerinfo.id);
|
||||
if (param->setup.callerinfo.name[0])
|
||||
|
@ -600,6 +628,7 @@ static void lcr_in_setup(struct chan_call *call, int message_type, union paramet
|
|||
ast->readformat = ast->rawreadformat = AST_FORMAT_ALAW;
|
||||
ast->writeformat = ast->rawwriteformat = AST_FORMAT_ALAW;
|
||||
#endif
|
||||
ast->priority = 1;
|
||||
ast->hangupcause = 0;
|
||||
|
||||
/* change state */
|
||||
|
@ -618,7 +647,7 @@ static void lcr_in_overlap(struct chan_call *call, int message_type, union param
|
|||
CDEBUG(call, call->ast, "Incomming setup acknowledge from LCR.\n");
|
||||
|
||||
/* send pending digits in dialque */
|
||||
if (call->dialque)
|
||||
if (call->dialque[0])
|
||||
send_dialque_to_lcr(call);
|
||||
/* change to overlap state */
|
||||
call->state = CHAN_LCR_STATE_OUT_DIALING;
|
||||
|
@ -657,10 +686,19 @@ static void lcr_in_alerting(struct chan_call *call, int message_type, union para
|
|||
*/
|
||||
static void lcr_in_connect(struct chan_call *call, int message_type, union parameter *param)
|
||||
{
|
||||
union parameter newparam;
|
||||
|
||||
CDEBUG(call, call->ast, "Incomming connect (answer) from LCR.\n");
|
||||
|
||||
/* change state */
|
||||
call->state = CHAN_LCR_STATE_CONNECT;
|
||||
/* request bchannel */
|
||||
if (!call->bchannel) {
|
||||
CDEBUG(call, call->ast, "Requesting B-channel.\n");
|
||||
memset(&newparam, 0, sizeof(union parameter));
|
||||
newparam.bchannel.type = BCHANNEL_REQUEST;
|
||||
send_message(MESSAGE_BCHANNEL, call->ref, &newparam);
|
||||
}
|
||||
/* copy connectinfo */
|
||||
memcpy(&call->connectinfo, ¶m->connectinfo, sizeof(struct connect_info));
|
||||
/* send event to asterisk */
|
||||
|
@ -693,7 +731,7 @@ static void lcr_in_disconnect(struct chan_call *call, int message_type, union pa
|
|||
}
|
||||
#endif
|
||||
/* release lcr with same cause */
|
||||
send_message(MESSAGE_RELEASE, call->ref, param);
|
||||
send_release_and_import(call, call->cause, call->location);
|
||||
call->ref = 0;
|
||||
/* change to release state */
|
||||
call->state = CHAN_LCR_STATE_RELEASE;
|
||||
|
@ -716,7 +754,7 @@ static void lcr_in_release(struct chan_call *call, int message_type, union param
|
|||
{
|
||||
struct ast_channel *ast = call->ast;
|
||||
|
||||
CDEBUG(call, call->ast, "Incomming release from LCR. (cause=%d)\n", param->disconnectinfo.cause);
|
||||
CDEBUG(call, call->ast, "Incomming release from LCR, releasing ref. (cause=%d)\n", param->disconnectinfo.cause);
|
||||
|
||||
/* release ref */
|
||||
call->ref = 0;
|
||||
|
@ -753,7 +791,7 @@ static void lcr_in_information(struct chan_call *call, int message_type, union p
|
|||
struct ast_frame fr;
|
||||
char *p;
|
||||
|
||||
CDEBUG(call, call->ast, "Incomming information from LCR. (dialing=%d)\n", param->information.id);
|
||||
CDEBUG(call, call->ast, "Incoming information from LCR. (dialing=%s)\n", param->information.id);
|
||||
|
||||
if (!ast) return;
|
||||
|
||||
|
@ -913,7 +951,7 @@ hier muesen alle bchannel-features gesetzt werden (pipeline...) falls sie vor de
|
|||
if (param->direction)
|
||||
{
|
||||
/* new ref from lcr */
|
||||
CDEBUG(NULL, NULL, "Received new ref by LCR, of call from LCR. (ref=%ld)\n", ref);
|
||||
CDEBUG(NULL, NULL, "Received new ref by LCR, due to incomming call. (ref=%ld)\n", ref);
|
||||
if (!ref || find_call_ref(ref))
|
||||
{
|
||||
CERROR(NULL, NULL, "Illegal new ref %ld received.\n", ref);
|
||||
|
@ -935,9 +973,7 @@ hier muesen alle bchannel-features gesetzt werden (pipeline...) falls sie vor de
|
|||
{
|
||||
/* send release, if ref does not exist */
|
||||
CDEBUG(NULL, NULL, "No call found, that requests a ref.\n");
|
||||
newparam.disconnectinfo.cause = CAUSE_NORMAL;
|
||||
newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
|
||||
send_message(MESSAGE_RELEASE, ref, &newparam);
|
||||
send_release_and_import(call, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL);
|
||||
return(0);
|
||||
}
|
||||
/* store new ref */
|
||||
|
@ -950,15 +986,9 @@ hier muesen alle bchannel-features gesetzt werden (pipeline...) falls sie vor de
|
|||
{
|
||||
/* send release */
|
||||
if (call->cause)
|
||||
{
|
||||
newparam.disconnectinfo.cause = call->cause;
|
||||
newparam.disconnectinfo.location = call->location;
|
||||
} else
|
||||
{
|
||||
newparam.disconnectinfo.cause = 16;
|
||||
newparam.disconnectinfo.location = 5;
|
||||
}
|
||||
send_message(MESSAGE_RELEASE, ref, &newparam);
|
||||
send_release_and_import(call, call->cause, call->location);
|
||||
else
|
||||
send_release_and_import(call, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL);
|
||||
/* free call */
|
||||
free_call(call);
|
||||
return(0);
|
||||
|
@ -1050,8 +1080,7 @@ static void release_all_calls(void)
|
|||
|
||||
again:
|
||||
call = call_first;
|
||||
while(call)
|
||||
{
|
||||
while(call) {
|
||||
/* no ast, so we may directly free call */
|
||||
if (!call->ast) {
|
||||
CDEBUG(call, NULL, "Freeing call, because no Asterisk channel is linked.\n");
|
||||
|
@ -1066,8 +1095,7 @@ again:
|
|||
/* release or queue release */
|
||||
call->ref = 0;
|
||||
call->state = CHAN_LCR_STATE_RELEASE;
|
||||
if (!call->pbx_started)
|
||||
{
|
||||
if (!call->pbx_started) {
|
||||
CDEBUG(call, call->ast, "Releasing call, because no Asterisk channel is not started.\n");
|
||||
ast_hangup(call->ast); // call will be destroyed here
|
||||
goto again;
|
||||
|
@ -1076,6 +1104,10 @@ again:
|
|||
ast_queue_hangup(call->ast);
|
||||
call = call->next;
|
||||
}
|
||||
|
||||
/* release all bchannels */
|
||||
while(bchannel_first)
|
||||
free_bchannel(bchannel_first);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1087,13 +1119,11 @@ int handle_socket(void)
|
|||
{
|
||||
int work = 0;
|
||||
int len;
|
||||
struct admin_message msg;
|
||||
struct admin_list *admin;
|
||||
|
||||
int sock;
|
||||
struct admin_message msg;
|
||||
|
||||
/* read from socket */
|
||||
len = read(sock, &msg, sizeof(msg));
|
||||
len = read(lcr_sock, &msg, sizeof(msg));
|
||||
if (len == 0)
|
||||
{
|
||||
CERROR(NULL, NULL, "Socket closed.\n");
|
||||
|
@ -1109,7 +1139,7 @@ int handle_socket(void)
|
|||
if (msg.message != ADMIN_MESSAGE)
|
||||
{
|
||||
CERROR(NULL, NULL, "Socket received illegal message %d.\n", msg.message);
|
||||
return(-1); // socket error
|
||||
return(-1);
|
||||
}
|
||||
receive_message(msg.u.msg.type, msg.u.msg.ref, &msg.u.msg.param);
|
||||
work = 1;
|
||||
|
@ -1126,7 +1156,7 @@ int handle_socket(void)
|
|||
if (!admin_first)
|
||||
return(work);
|
||||
admin = admin_first;
|
||||
len = write(sock, &admin->msg, sizeof(msg));
|
||||
len = write(lcr_sock, &admin->msg, sizeof(msg));
|
||||
if (len == 0)
|
||||
{
|
||||
CERROR(NULL, NULL, "Socket closed.\n");
|
||||
|
@ -1162,7 +1192,6 @@ int handle_socket(void)
|
|||
int open_socket(void)
|
||||
{
|
||||
int ret;
|
||||
int sock;
|
||||
char *socket_name = SOCKET_NAME;
|
||||
int conn;
|
||||
struct sockaddr_un sock_address;
|
||||
|
@ -1170,10 +1199,10 @@ int open_socket(void)
|
|||
union parameter param;
|
||||
|
||||
/* open socket */
|
||||
if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
|
||||
if ((lcr_sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
|
||||
{
|
||||
CERROR(NULL, NULL, "Failed to create socket.\n");
|
||||
return(sock);
|
||||
return(lcr_sock);
|
||||
}
|
||||
|
||||
/* set socket address and name */
|
||||
|
@ -1182,17 +1211,19 @@ int open_socket(void)
|
|||
strcpy(sock_address.sun_path, socket_name);
|
||||
|
||||
/* connect socket */
|
||||
if ((conn = connect(sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0)
|
||||
if ((conn = connect(lcr_sock, (struct sockaddr *)&sock_address, SUN_LEN(&sock_address))) < 0)
|
||||
{
|
||||
close(sock);
|
||||
CERROR(NULL, NULL, "Failed to connect to socket '%s'. Is LCR running?\n", sock_address.sun_path);
|
||||
close(lcr_sock);
|
||||
lcr_sock = -1;
|
||||
CDEBUG(NULL, NULL, "Failed to connect to socket '%s'. Is LCR running?\n", sock_address.sun_path);
|
||||
return(conn);
|
||||
}
|
||||
|
||||
/* set non-blocking io */
|
||||
if ((ret = ioctl(sock, FIONBIO, (unsigned char *)(&on))) < 0)
|
||||
if ((ret = ioctl(lcr_sock, FIONBIO, (unsigned char *)(&on))) < 0)
|
||||
{
|
||||
close(sock);
|
||||
close(lcr_sock);
|
||||
lcr_sock = -1;
|
||||
CERROR(NULL, NULL, "Failed to set socket into non-blocking IO.\n");
|
||||
return(ret);
|
||||
}
|
||||
|
@ -1202,14 +1233,30 @@ int open_socket(void)
|
|||
strcpy(param.hello.application, "asterisk");
|
||||
send_message(MESSAGE_HELLO, 0, ¶m);
|
||||
|
||||
return(sock);
|
||||
return(lcr_sock);
|
||||
}
|
||||
|
||||
void close_socket(int sock)
|
||||
void close_socket(void)
|
||||
{
|
||||
struct admin_list *admin, *temp;
|
||||
|
||||
/* flush pending messages */
|
||||
admin = admin_first;
|
||||
while(admin) {
|
||||
temp = admin;
|
||||
admin = admin->next;
|
||||
free(temp);
|
||||
}
|
||||
admin_first = NULL;
|
||||
|
||||
/* close socket */
|
||||
if (socket >= 0)
|
||||
close(sock);
|
||||
if (lcr_sock >= 0)
|
||||
close(lcr_sock);
|
||||
lcr_sock = -1;
|
||||
}
|
||||
|
||||
void sighandler(int sigset)
|
||||
{
|
||||
}
|
||||
|
||||
static void *chan_thread(void *arg)
|
||||
|
@ -1220,9 +1267,11 @@ static void *chan_thread(void *arg)
|
|||
time_t retry = 0, now;
|
||||
|
||||
bchannel_pid = getpid();
|
||||
|
||||
// signal(SIGPIPE, sighandler);
|
||||
|
||||
memset(¶m, 0, sizeof(union parameter));
|
||||
if (lcr_sock > 0)
|
||||
if (lcr_sock < 0)
|
||||
time(&retry);
|
||||
|
||||
ast_mutex_lock(&chan_lock);
|
||||
|
@ -1235,8 +1284,7 @@ static void *chan_thread(void *arg)
|
|||
ret = handle_socket();
|
||||
if (ret < 0) {
|
||||
CERROR(NULL, NULL, "Handling of socket failed - closing for some seconds.\n");
|
||||
close_socket(lcr_sock);
|
||||
lcr_sock = -1;
|
||||
close_socket();
|
||||
release_all_calls();
|
||||
time(&retry);
|
||||
}
|
||||
|
@ -1245,9 +1293,9 @@ static void *chan_thread(void *arg)
|
|||
} else {
|
||||
time(&now);
|
||||
if (retry && now-retry > 5) {
|
||||
CERROR(NULL, NULL, "Retry to open socket.\n");
|
||||
CDEBUG(NULL, NULL, "Retry to open socket.\n");
|
||||
retry = 0;
|
||||
if (!(lcr_sock = open_socket())) {
|
||||
if (open_socket() < 0) {
|
||||
time(&retry);
|
||||
}
|
||||
work = 1;
|
||||
|
@ -1267,10 +1315,14 @@ static void *chan_thread(void *arg)
|
|||
}
|
||||
}
|
||||
|
||||
close_socket();
|
||||
|
||||
CERROR(NULL, NULL, "Thread exit.\n");
|
||||
|
||||
ast_mutex_unlock(&chan_lock);
|
||||
|
||||
// signal(SIGPIPE, SIG_DFL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1312,9 +1364,10 @@ struct ast_channel *lcr_request(const char *type, int format, void *data, int *c
|
|||
return NULL;
|
||||
}
|
||||
/* link together */
|
||||
ast->tech_pvt = call;
|
||||
call->ast = ast;
|
||||
ast->tech_pvt = call;
|
||||
ast->tech = &lcr_tech;
|
||||
ast->fds[0] = call->pipe[0];
|
||||
/* configure channel */
|
||||
#ifdef TODO
|
||||
snprintf(ast->name, sizeof(ast->name), "%s/%d", lcr_type, ++glob_channel);
|
||||
|
@ -1329,6 +1382,7 @@ struct ast_channel *lcr_request(const char *type, int format, void *data, int *c
|
|||
ast->readformat = ast->rawreadformat = AST_FORMAT_ALAW;
|
||||
ast->writeformat = ast->rawwriteformat = AST_FORMAT_ALAW;
|
||||
#endif
|
||||
ast->priority = 1;
|
||||
ast->hangupcause = 0;
|
||||
/* send MESSAGE_NEWREF */
|
||||
memset(&newparam, 0, sizeof(union parameter));
|
||||
|
@ -1359,6 +1413,7 @@ static int lcr_call(struct ast_channel *ast, char *dest, int timeout)
|
|||
|
||||
CDEBUG(call, ast, "Received call from Asterisk.\n");
|
||||
|
||||
#warning was passiert zwischen lcr_request und lcr_call ?
|
||||
call->pbx_started = 1;
|
||||
|
||||
/* send setup message, if we already have a callref */
|
||||
|
@ -1435,6 +1490,13 @@ static int lcr_answer(struct ast_channel *ast)
|
|||
send_message(MESSAGE_CONNECT, call->ref, &newparam);
|
||||
/* change state */
|
||||
call->state = CHAN_LCR_STATE_CONNECT;
|
||||
/* request bchannel */
|
||||
if (!call->bchannel) {
|
||||
CDEBUG(call, ast, "Requesting B-channel.\n");
|
||||
memset(&newparam, 0, sizeof(union parameter));
|
||||
newparam.bchannel.type = BCHANNEL_REQUEST;
|
||||
send_message(MESSAGE_BCHANNEL, call->ref, &newparam);
|
||||
}
|
||||
|
||||
ast_mutex_unlock(&chan_lock);
|
||||
return 0;
|
||||
|
@ -1442,7 +1504,6 @@ static int lcr_answer(struct ast_channel *ast)
|
|||
|
||||
static int lcr_hangup(struct ast_channel *ast)
|
||||
{
|
||||
union parameter newparam;
|
||||
struct chan_call *call;
|
||||
pthread_t tid = pthread_self();
|
||||
|
||||
|
@ -1468,10 +1529,10 @@ static int lcr_hangup(struct ast_channel *ast)
|
|||
{
|
||||
/* release */
|
||||
CDEBUG(call, ast, "Releasing ref and freeing call instance.\n");
|
||||
memset(&newparam, 0, sizeof(union parameter));
|
||||
newparam.disconnectinfo.cause = CAUSE_RESSOURCEUNAVAIL;
|
||||
newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
|
||||
send_message(MESSAGE_RELEASE, call->ref, &newparam);
|
||||
if (ast->hangupcause > 0)
|
||||
send_release_and_import(call, ast->hangupcause, LOCATION_PRIVATE_LOCAL);
|
||||
else
|
||||
send_release_and_import(call, CAUSE_RESSOURCEUNAVAIL, LOCATION_PRIVATE_LOCAL);
|
||||
/* remove call */
|
||||
free_call(call);
|
||||
if (!pthread_equal(tid, chan_tid))
|
||||
|
@ -1500,24 +1561,24 @@ static int lcr_hangup(struct ast_channel *ast)
|
|||
static int lcr_write(struct ast_channel *ast, struct ast_frame *f)
|
||||
{
|
||||
struct chan_call *call;
|
||||
unsigned char buffer[1024], *s, *d = buffer;
|
||||
int i, ii;
|
||||
|
||||
if (!f->subclass)
|
||||
CDEBUG(NULL, ast, "No subclass\n");
|
||||
#ifdef TODO
|
||||
config
|
||||
#else
|
||||
if (!(f->subclass & AST_FORMAT_ALAW))
|
||||
#endif
|
||||
CDEBUG(NULL, ast, "Unexpected format.\n");
|
||||
|
||||
ast_mutex_lock(&chan_lock);
|
||||
call = ast->tech_pvt;
|
||||
if (!call) {
|
||||
ast_mutex_unlock(&chan_lock);
|
||||
return -1;
|
||||
}
|
||||
if (call->bchannel && ((ii = f->samples)))
|
||||
{
|
||||
if (ii > sizeof(buffer))
|
||||
ii = sizeof(buffer);
|
||||
s = f->data;
|
||||
for (i = 0; i < ii; i++)
|
||||
*d++ = flip_bits[*s++];
|
||||
bchannel_transmit(call->bchannel, buffer, ii);
|
||||
}
|
||||
if (call->bchannel && f->samples)
|
||||
bchannel_transmit(call->bchannel, f->data, f->samples);
|
||||
ast_mutex_unlock(&chan_lock);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1535,9 +1596,14 @@ static struct ast_frame *lcr_read(struct ast_channel *ast)
|
|||
ast_mutex_unlock(&chan_lock);
|
||||
return NULL;
|
||||
}
|
||||
len = read(call->pipe[0], call->read_buff, sizeof(call->read_buff));
|
||||
if (len <= 0)
|
||||
return NULL;
|
||||
if (call->pipe[0] > -1) {
|
||||
len = read(call->pipe[0], call->read_buff, sizeof(call->read_buff));
|
||||
if (len <= 0) {
|
||||
close(call->pipe[0]);
|
||||
call->pipe[0] = -1;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
p = call->read_buff;
|
||||
for (i = 0; i < len; i++) {
|
||||
|
@ -1548,8 +1614,9 @@ static struct ast_frame *lcr_read(struct ast_channel *ast)
|
|||
call->read_fr.frametype = AST_FRAME_VOICE;
|
||||
#ifdef TODO
|
||||
format aus config
|
||||
#endif
|
||||
#else
|
||||
call->read_fr.subclass = AST_FORMAT_ALAW;
|
||||
#endif
|
||||
call->read_fr.datalen = len;
|
||||
call->read_fr.samples = len;
|
||||
call->read_fr.delivery = ast_tv(0,0);
|
||||
|
@ -1562,7 +1629,7 @@ static struct ast_frame *lcr_read(struct ast_channel *ast)
|
|||
static int lcr_indicate(struct ast_channel *ast, int cond, const void *data, size_t datalen)
|
||||
{
|
||||
union parameter newparam;
|
||||
int res = -1;
|
||||
int res = 0;
|
||||
struct chan_call *call;
|
||||
|
||||
ast_mutex_lock(&chan_lock);
|
||||
|
@ -1576,37 +1643,60 @@ static int lcr_indicate(struct ast_channel *ast, int cond, const void *data, siz
|
|||
switch (cond) {
|
||||
case AST_CONTROL_BUSY:
|
||||
CDEBUG(call, ast, "Received indicate AST_CONTROL_BUSY from Asterisk.\n");
|
||||
/* send message to lcr */
|
||||
memset(&newparam, 0, sizeof(union parameter));
|
||||
newparam.disconnectinfo.cause = 17;
|
||||
newparam.disconnectinfo.location = 5;
|
||||
send_message(MESSAGE_DISCONNECT, call->ref, &newparam);
|
||||
/* change state */
|
||||
call->state = CHAN_LCR_STATE_OUT_DISCONNECT;
|
||||
/* return */
|
||||
ast_mutex_unlock(&chan_lock);
|
||||
return 0;
|
||||
ast_setstate(ast, AST_STATE_BUSY);
|
||||
if (call->state != CHAN_LCR_STATE_OUT_DISCONNECT) {
|
||||
/* send message to lcr */
|
||||
memset(&newparam, 0, sizeof(union parameter));
|
||||
newparam.disconnectinfo.cause = 17;
|
||||
newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
|
||||
send_message(MESSAGE_DISCONNECT, call->ref, &newparam);
|
||||
/* change state */
|
||||
call->state = CHAN_LCR_STATE_OUT_DISCONNECT;
|
||||
}
|
||||
break;
|
||||
case AST_CONTROL_CONGESTION:
|
||||
CDEBUG(call, ast, "Received indicate AST_CONTROL_CONGESTION from Asterisk.\n");
|
||||
/* return */
|
||||
ast_mutex_unlock(&chan_lock);
|
||||
return -1;
|
||||
CDEBUG(call, ast, "Received indicate AST_CONTROL_CONGESTION from Asterisk. (cause %d)\n", ast->hangupcause);
|
||||
if (call->state != CHAN_LCR_STATE_OUT_DISCONNECT) {
|
||||
/* send message to lcr */
|
||||
memset(&newparam, 0, sizeof(union parameter));
|
||||
newparam.disconnectinfo.cause = ast->hangupcause;
|
||||
newparam.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
|
||||
send_message(MESSAGE_DISCONNECT, call->ref, &newparam);
|
||||
/* change state */
|
||||
call->state = CHAN_LCR_STATE_OUT_DISCONNECT;
|
||||
}
|
||||
break;
|
||||
case AST_CONTROL_PROCEEDING:
|
||||
CDEBUG(call, ast, "Received indicate AST_CONTROL_PROCEEDING from Asterisk.\n");
|
||||
if (call->state == CHAN_LCR_STATE_IN_SETUP
|
||||
|| call->state == CHAN_LCR_STATE_IN_DIALING) {
|
||||
/* send message to lcr */
|
||||
memset(&newparam, 0, sizeof(union parameter));
|
||||
send_message(MESSAGE_PROCEEDING, call->ref, &newparam);
|
||||
/* change state */
|
||||
call->state = CHAN_LCR_STATE_IN_PROCEEDING;
|
||||
}
|
||||
break;
|
||||
case AST_CONTROL_RINGING:
|
||||
CDEBUG(call, ast, "Received indicate AST_CONTROL_RINGING from Asterisk.\n");
|
||||
/* send message to lcr */
|
||||
memset(&newparam, 0, sizeof(union parameter));
|
||||
send_message(MESSAGE_ALERTING, call->ref, &newparam);
|
||||
/* change state */
|
||||
call->state = CHAN_LCR_STATE_OUT_ALERTING;
|
||||
/* return */
|
||||
ast_mutex_unlock(&chan_lock);
|
||||
return 0;
|
||||
ast_setstate(ast, AST_STATE_RINGING);
|
||||
if (call->state == CHAN_LCR_STATE_IN_SETUP
|
||||
|| call->state == CHAN_LCR_STATE_IN_DIALING
|
||||
|| call->state == CHAN_LCR_STATE_IN_PROCEEDING) {
|
||||
/* send message to lcr */
|
||||
memset(&newparam, 0, sizeof(union parameter));
|
||||
send_message(MESSAGE_ALERTING, call->ref, &newparam);
|
||||
/* change state */
|
||||
call->state = CHAN_LCR_STATE_IN_ALERTING;
|
||||
}
|
||||
break;
|
||||
case -1:
|
||||
/* return */
|
||||
ast_mutex_unlock(&chan_lock);
|
||||
return 0;
|
||||
CDEBUG(call, ast, "Received indicate -1.\n");
|
||||
res = -1;
|
||||
break;
|
||||
|
||||
case AST_CONTROL_VIDUPDATE:
|
||||
CDEBUG(call, ast, "Received indicate AST_CONTROL_VIDUPDATE.\n");
|
||||
res = -1;
|
||||
break;
|
||||
case AST_CONTROL_HOLD:
|
||||
|
@ -1626,14 +1716,58 @@ static int lcr_indicate(struct ast_channel *ast, int cond, const void *data, siz
|
|||
|
||||
default:
|
||||
CERROR(call, ast, "Received indicate from Asterisk with unknown condition %d.\n", cond);
|
||||
/* return */
|
||||
ast_mutex_unlock(&chan_lock);
|
||||
return -1;
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* return */
|
||||
ast_mutex_unlock(&chan_lock);
|
||||
return 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* fixup asterisk
|
||||
*/
|
||||
static int lcr_fixup(struct ast_channel *oldast, struct ast_channel *newast)
|
||||
{
|
||||
struct chan_call *call;
|
||||
|
||||
ast_mutex_lock(&chan_lock);
|
||||
call = oldast->tech_pvt;
|
||||
if (!call) {
|
||||
CERROR(NULL, oldast, "Received fixup from Asterisk, but no call instance exists.\n");
|
||||
ast_mutex_unlock(&chan_lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
CDEBUG(call, oldast, "Received fixup from Asterisk.\n");
|
||||
call->ast = newast;
|
||||
ast_mutex_lock(&chan_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* send_text asterisk
|
||||
*/
|
||||
static int lcr_send_text(struct ast_channel *ast, const char *text)
|
||||
{
|
||||
struct chan_call *call;
|
||||
union parameter newparam;
|
||||
|
||||
ast_mutex_lock(&chan_lock);
|
||||
call = ast->tech_pvt;
|
||||
if (!call) {
|
||||
CERROR(NULL, ast, "Received send_text from Asterisk, but no call instance exists.\n");
|
||||
ast_mutex_unlock(&chan_lock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
CDEBUG(call, ast, "Received send_text from Asterisk. (text=%s)\n", text);
|
||||
memset(&newparam, 0, sizeof(union parameter));
|
||||
strncpy(newparam.notifyinfo.display, text, sizeof(newparam.notifyinfo.display)-1);
|
||||
send_message(MESSAGE_NOTIFY, call->ref, &newparam);
|
||||
ast_mutex_lock(&chan_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1752,8 +1886,8 @@ static struct ast_channel_tech lcr_tech = {
|
|||
.read=lcr_read,
|
||||
.write=lcr_write,
|
||||
.indicate=lcr_indicate,
|
||||
// .fixup=lcr_fixup,
|
||||
// .send_text=lcr_send_text,
|
||||
.fixup=lcr_fixup,
|
||||
.send_text=lcr_send_text,
|
||||
.properties=0
|
||||
};
|
||||
|
||||
|
@ -1851,31 +1985,32 @@ static struct ast_cli_entry cli_port_unload =
|
|||
*/
|
||||
int load_module(void)
|
||||
{
|
||||
int i;
|
||||
u_short i;
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
for (i = 0; i < 256; i++) {
|
||||
flip_bits[i] = (i>>7) | ((i>>5)&2) | ((i>>3)&4) | ((i>>1)&8)
|
||||
|| (i<<7) | ((i&2)<<5) | ((i&4)<<3) | ((i&8)<<1);
|
||||
| (i<<7) | ((i&2)<<5) | ((i&4)<<3) | ((i&8)<<1);
|
||||
}
|
||||
|
||||
ast_mutex_init(&chan_lock);
|
||||
ast_mutex_init(&log_lock);
|
||||
|
||||
if (!(lcr_sock = open_socket())) {
|
||||
|
||||
if (open_socket() < 0) {
|
||||
/* continue with closed socket */
|
||||
}
|
||||
|
||||
if (!bchannel_initialize()) {
|
||||
if (bchannel_initialize()) {
|
||||
CERROR(NULL, NULL, "Unable to open mISDN device\n");
|
||||
close_socket(lcr_sock);
|
||||
return -1;
|
||||
close_socket();
|
||||
return AST_MODULE_LOAD_DECLINE;
|
||||
}
|
||||
mISDN_created = 1;
|
||||
|
||||
if (ast_channel_register(&lcr_tech)) {
|
||||
CERROR(NULL, NULL, "Unable to register channel class\n");
|
||||
bchannel_deinitialize();
|
||||
close_socket(lcr_sock);
|
||||
return -1;
|
||||
close_socket();
|
||||
return AST_MODULE_LOAD_DECLINE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
@ -1916,9 +2051,9 @@ int load_module(void)
|
|||
{
|
||||
/* failed to create thread */
|
||||
bchannel_deinitialize();
|
||||
close_socket(lcr_sock);
|
||||
close_socket();
|
||||
ast_channel_unregister(&lcr_tech);
|
||||
return -1;
|
||||
return AST_MODULE_LOAD_DECLINE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1953,9 +2088,10 @@ int reload_module(void)
|
|||
}
|
||||
|
||||
#ifdef TODO
|
||||
mutex init fehlt noch
|
||||
ast_mutex_t usecnt_lock;
|
||||
wech damit
|
||||
|
||||
int usecnt;
|
||||
ast_mutex_t usecnt_lock;
|
||||
|
||||
int usecount(void)
|
||||
{
|
||||
|
@ -1965,7 +2101,6 @@ int usecount(void)
|
|||
ast_mutex_unlock(&usecnt_lock);
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
char *desc="Channel driver for lcr";
|
||||
|
@ -1979,5 +2114,13 @@ char *key(void)
|
|||
{
|
||||
return ASTERISK_GPL_KEY;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define AST_MODULE "chan_lcr"
|
||||
|
||||
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Channel driver for Linux-Call-Router Support (ISDN BRI/PRI)",
|
||||
.load = load_module,
|
||||
.unload = unload_module,
|
||||
.reload = reload_module,
|
||||
);
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ enum {
|
|||
};
|
||||
|
||||
|
||||
#define CERROR(call, ast, arg...) chan_lcr_log(__LOG_ERROR, __FILE__, __LINE__, call, ast, ##arg)
|
||||
#define CDEBUG(call, ast, arg...) chan_lcr_log(__LOG_DEBUG, __FILE__, __LINE__, call, ast, ##arg)
|
||||
void chan_lcr_log(int type, const char *file, int line, struct chan_call *call, struct ast_channel *ast, const char *fmt, ...);
|
||||
|
||||
#define CERROR(call, ast, arg...) chan_lcr_log(__LOG_ERROR, __FILE__, __LINE__, __FUNCTION__, call, ast, ##arg)
|
||||
#define CDEBUG(call, ast, arg...) chan_lcr_log(__LOG_NOTICE, __FILE__, __LINE__, __FUNCTION__, call, ast, ##arg)
|
||||
void chan_lcr_log(int type, const char *file, int line, const char *function, struct chan_call *call, struct ast_channel *ast, const char *fmt, ...);
|
||||
extern unsigned char flip_bits[256];
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
OUTDATED, please update
|
||||
|
||||
## -*- autoconf -*-
|
||||
|
||||
dnl This file is part of linux-call-router
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# PBX4Linux routing configuration "routing.conf"
|
||||
# Linux-Call-Router routing configuration "routing.conf"
|
||||
|
||||
|
||||
# Ruleset: MAIN
|
||||
|
|
65
dss1.h
65
dss1.h
|
@ -15,13 +15,8 @@ class Pdss1 : public PmISDN
|
|||
public:
|
||||
Pdss1(int type, struct mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive);
|
||||
~Pdss1();
|
||||
#ifdef SOCKET_MISDN
|
||||
unsigned int p_m_d_l3id; /* current l3 process id */
|
||||
void message_isdn(unsigned int cmd, unsigned int pid, struct l3_msg *l3m);
|
||||
#else
|
||||
int p_m_d_l3id; /* current l3 process id */
|
||||
void message_isdn(unsigned long prim, unsigned long dinfo, void *data);
|
||||
#endif
|
||||
int p_m_d_ces; /* ntmode: tei&sapi */
|
||||
int handler(void);
|
||||
int message_epoint(unsigned long epoint_id, int message, union parameter *param);
|
||||
|
@ -36,7 +31,6 @@ class Pdss1 : public PmISDN
|
|||
void new_state(int state); /* set new state */
|
||||
// void isdn_show_send_message(unsigned long prim, msg_t *msg);
|
||||
int hunt_bchannel(int exclusive, int channel);
|
||||
#ifdef SOCKET_MISDN
|
||||
int received_first_reply_to_setup(unsigned long cmd, int channel, int exclusive);
|
||||
void information_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m);
|
||||
void setup_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m);
|
||||
|
@ -55,26 +49,6 @@ class Pdss1 : public PmISDN
|
|||
void retrieve_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m);
|
||||
void suspend_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m);
|
||||
void resume_ind(unsigned int cmd, unsigned int pid, struct l3_msg *l3m);
|
||||
#else
|
||||
int received_first_reply_to_setup(unsigned long prim, int channel, int exclusive);
|
||||
void information_ind(unsigned long prim, unsigned long dinfo, void *data);
|
||||
void setup_ind(unsigned long prim, unsigned long dinfo, void *data);
|
||||
void setup_acknowledge_ind(unsigned long prim, unsigned long dinfo, void *data);
|
||||
void proceeding_ind(unsigned long prim, unsigned long dinfo, void *data);
|
||||
void alerting_ind(unsigned long prim, unsigned long dinfo, void *data);
|
||||
void connect_ind(unsigned long prim, unsigned long dinfo, void *data);
|
||||
void disconnect_ind(unsigned long prim, unsigned long dinfo, void *data);
|
||||
void release_ind(unsigned long prim, unsigned long dinfo, void *data);
|
||||
void release_complete_ind(unsigned long prim, unsigned long dinfo, void *data);
|
||||
void disconnect_ind_i(unsigned long prim, unsigned long dinfo, void *data);
|
||||
void t312_timeout_ind(unsigned long prim, unsigned long dinfo, void *data);
|
||||
void notify_ind(unsigned long prim, unsigned long dinfo, void *data);
|
||||
void facility_ind(unsigned long prim, unsigned long dinfo, void *data);
|
||||
void hold_ind(unsigned long prim, unsigned long dinfo, void *data);
|
||||
void retrieve_ind(unsigned long prim, unsigned long dinfo, void *data);
|
||||
void suspend_ind(unsigned long prim, unsigned long dinfo, void *data);
|
||||
void resume_ind(unsigned long prim, unsigned long dinfo, void *data);
|
||||
#endif
|
||||
void message_information(unsigned long epoint_id, int message_id, union parameter *param);
|
||||
void message_setup(unsigned long epoint_id, int message_id, union parameter *param);
|
||||
void message_notify(unsigned long epoint_id, int message_id, union parameter *param);
|
||||
|
@ -87,7 +61,6 @@ class Pdss1 : public PmISDN
|
|||
void message_release(unsigned long epoint_id, int message_id, union parameter *param);
|
||||
|
||||
/* IE conversion */
|
||||
#ifdef SOCKET_MISDN
|
||||
void enc_ie_complete(struct l3_msg *l3m, int complete);
|
||||
void dec_ie_complete(struct l3_msg *l3m, int *complete);
|
||||
void enc_ie_bearer(struct l3_msg *l3m, int coding, int capability, int mode, int rate, int multi, int user);
|
||||
|
@ -124,44 +97,6 @@ class Pdss1 : public PmISDN
|
|||
void dec_facility_centrex(struct l3_msg *l3m, unsigned char *cnip, int cnip_len);
|
||||
void enc_ie_useruser(struct l3_msg *l3m, int protocol, unsigned char *user, int user_len);
|
||||
void dec_ie_useruser(struct l3_msg *l3m, int *protocol, unsigned char *user, int *user_len);
|
||||
#else
|
||||
void enc_ie_complete(unsigned char **ntmode, msg_t *msg, int complete);
|
||||
void dec_ie_complete(unsigned char *p, Q931_info_t *qi, int *complete);
|
||||
void enc_ie_bearer(unsigned char **ntmode, msg_t *msg, int coding, int capability, int mode, int rate, int multi, int user);
|
||||
void dec_ie_bearer(unsigned char *p, Q931_info_t *qi, int *coding, int *capability, int *mode, int *rate, int *multi, int *user);
|
||||
void enc_ie_call_id(unsigned char **ntmode, msg_t *msg, unsigned char *callid, int callid_len);
|
||||
void dec_ie_call_id(unsigned char *p, Q931_info_t *qi, unsigned char *callid, int *callid_len);
|
||||
void enc_ie_called_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, unsigned char *number);
|
||||
void dec_ie_called_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, unsigned char *number, int number_len);
|
||||
void enc_ie_calling_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, unsigned char *number);
|
||||
void dec_ie_calling_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, unsigned char *number, int number_len);
|
||||
void enc_ie_connected_pn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, unsigned char *number);
|
||||
void dec_ie_connected_pn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, unsigned char *number, int number_len);
|
||||
void enc_ie_cause(unsigned char **ntmode, msg_t *msg, int location, int cause);
|
||||
void dec_ie_cause(unsigned char *p, Q931_info_t *qi, int *location, int *cause);
|
||||
void enc_ie_channel_id(unsigned char **ntmode, msg_t *msg, int exclusive, int channel);
|
||||
void dec_ie_channel_id(unsigned char *p, Q931_info_t *qi, int *exclusive, int *channel);
|
||||
void enc_ie_date(unsigned char **ntmode, msg_t *msg, time_t ti, int seconds);
|
||||
void enc_ie_display(unsigned char **ntmode, msg_t *msg, unsigned char *display);
|
||||
void dec_ie_display(unsigned char *p, Q931_info_t *qi, unsigned char *display, int display_len);
|
||||
void enc_ie_keypad(unsigned char **ntmode, msg_t *msg, unsigned char *keypad);
|
||||
void dec_ie_keypad(unsigned char *p, Q931_info_t *qi, unsigned char *keypad, int keypad_len);
|
||||
void enc_ie_notify(unsigned char **ntmode, msg_t *msg, int notify);
|
||||
void dec_ie_notify(unsigned char *p, Q931_info_t *qi, int *notify);
|
||||
void enc_ie_progress(unsigned char **ntmode, msg_t *msg, int coding, int location, int progress);
|
||||
void dec_ie_progress(unsigned char *p, Q931_info_t *qi, int *coding, int *location, int *progress);
|
||||
void enc_ie_hlc(unsigned char **ntmode, msg_t *msg, int coding, int interpretation, int presentation, int hlc, int exthlc);
|
||||
void dec_ie_hlc(unsigned char *p, Q931_info_t *qi, int *coding, int *interpretation, int *presentation, int *hlc, int *exthlc);
|
||||
void enc_ie_redir_nr(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, int screen, int reason, unsigned char *number);
|
||||
void dec_ie_redir_nr(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, int *screen, int *reason, unsigned char *number, int number_len);
|
||||
void enc_ie_redir_dn(unsigned char **ntmode, msg_t *msg, int type, int plan, int present, unsigned char *number);
|
||||
void dec_ie_redir_dn(unsigned char *p, Q931_info_t *qi, int *type, int *plan, int *present, unsigned char *number, int number_len);
|
||||
void enc_ie_facility(unsigned char **ntmode, msg_t *msg, unsigned char *facility, int facility_len);
|
||||
void dec_ie_facility(unsigned char *p, Q931_info_t *qi, unsigned char *facility, int *facility_len);
|
||||
void dec_facility_centrex(unsigned char *p, Q931_info_t *qi, unsigned char *cnip, int cnip_len);
|
||||
void enc_ie_useruser(unsigned char **ntmode, msg_t *msg, int protocol, unsigned char *user, int user_len);
|
||||
void dec_ie_useruser(unsigned char *p, Q931_info_t *qi, int *protocol, unsigned char *user, int *user_len);
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
|
13
genrc.c
13
genrc.c
|
@ -30,16 +30,16 @@ static struct cards {
|
|||
int isac;
|
||||
int ports;
|
||||
} cards[] = {
|
||||
{ "AVM Fritz PCI (PNP)", "avmfritz", 0, 1, 1},
|
||||
// { "AVM Fritz PCI (PNP)", "avmfritz", 0, 1, 1},
|
||||
{ "HFC PCI (Cologne Chip)", "hfcpci", 1, 0, 1},
|
||||
{ "HFC-4S 4 S/T Ports (Cologne Chip)", "hfcmulti", 1, 0, 4},
|
||||
{ "HFC-8S 8 S/T Ports (Cologne Chip)", "hfcmulti", 1, 0, 8},
|
||||
{ "HFC-E1 1 E1 Port (Cologne Chip)", "hfcmulti", 1, 0, 1},
|
||||
{ "HFC-S USB (Cologne Chip)", "hfcsusb", 1, 0, 1},
|
||||
{ "HFC-S MINI (Cologne Chip)", "hfcsmini", 1, 0, 1},
|
||||
{ "XHFC (Cologne Chip)", "xhfc", 1, 0, 1},
|
||||
{ "Sedlbaur FAX", "sedlfax", 0, 1, 1},
|
||||
{ "Winbond 6692 PCI", "w6692pci", 0, 0, 1},
|
||||
// { "HFC-S MINI (Cologne Chip)", "hfcsmini", 1, 0, 1},
|
||||
// { "XHFC (Cologne Chip)", "xhfc", 1, 0, 1},
|
||||
// { "Sedlbaur FAX", "sedlfax", 0, 1, 1},
|
||||
// { "Winbond 6692 PCI", "w6692pci", 0, 0, 1},
|
||||
{ NULL, NULL, 0, 0},
|
||||
};
|
||||
|
||||
|
@ -50,6 +50,9 @@ int main(void)
|
|||
char input[256];
|
||||
char protocol[1024], layermask[1024], types[256];
|
||||
|
||||
printf("This program is outdated and requires update to mISDN V2 API\n");
|
||||
return (0);
|
||||
|
||||
printf("\n\nThis program generates a script, which is used to start/stop/restart mISDN\n");
|
||||
printf("driver. All configuration of cards is done for using with the LCR.\n");
|
||||
|
||||
|
|
|
@ -187,7 +187,6 @@ static int inter_ptmp(struct interface *interface, char *filename, int line, cha
|
|||
#endif
|
||||
static int inter_nt(struct interface *interface, char *filename, int line, char *parameter, char *value)
|
||||
{
|
||||
#ifdef SOCKET_MISDN
|
||||
struct interface_port *ifport;
|
||||
|
||||
/* port in chain ? */
|
||||
|
@ -207,7 +206,6 @@ static int inter_nt(struct interface *interface, char *filename, int line, char
|
|||
return(-1);
|
||||
}
|
||||
ifport->nt = 1;
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
static int inter_tones(struct interface *interface, char *filename, int line, char *parameter, char *value)
|
||||
|
@ -875,11 +873,7 @@ struct interface_param interface_param[] = {
|
|||
|
||||
{"nt", &inter_nt, "",
|
||||
"The given port above is opened in NT-mode.\n"
|
||||
#ifdef SOCKET_MISDN
|
||||
"This is required on interfaces that support both NT-mode and TE-mode.\n"
|
||||
#else
|
||||
"This parameter is only required for socket based mISDN driver.\n"
|
||||
#endif
|
||||
"This parameter must follow a 'port' parameter."},
|
||||
|
||||
{"layer2hold", &inter_l2hold, "yes | no",
|
||||
|
|
22
lcradmin.c
22
lcradmin.c
|
@ -359,7 +359,7 @@ int debug_epoint(struct admin_message *msg, struct admin_message *m, int line, i
|
|||
}
|
||||
/* loop all related ports */
|
||||
ltee = 0;
|
||||
j = msg->u.s.interfaces+msg->u.s.joins+msg->u.s.epoints;
|
||||
j = msg->u.s.interfaces+msg->u.s.remotes+msg->u.s.joins+msg->u.s.epoints;
|
||||
jj = j + msg->u.s.ports;
|
||||
while(j < jj)
|
||||
{
|
||||
|
@ -416,7 +416,7 @@ int debug_join(struct admin_message *msg, struct admin_message *m, int line, int
|
|||
addstr(buffer);
|
||||
}
|
||||
/* find number of epoints */
|
||||
j = msg->u.s.interfaces+msg->u.s.joins;
|
||||
j = msg->u.s.interfaces+msg->u.s.remotes+msg->u.s.joins;
|
||||
jj = j + msg->u.s.epoints;
|
||||
i = 0;
|
||||
while(j < jj)
|
||||
|
@ -426,7 +426,7 @@ int debug_join(struct admin_message *msg, struct admin_message *m, int line, int
|
|||
j++;
|
||||
}
|
||||
/* loop all related endpoints */
|
||||
j = msg->u.s.interfaces+msg->u.s.joins;
|
||||
j = msg->u.s.interfaces+msg->u.s.remotes+msg->u.s.joins;
|
||||
jj = j + msg->u.s.epoints;
|
||||
while(j < jj)
|
||||
{
|
||||
|
@ -778,7 +778,7 @@ char *admin_state(int sock, char *argv[])
|
|||
if (m[i].u.i.port[j])
|
||||
{
|
||||
/* search for port */
|
||||
l = msg.u.s.interfaces+msg.u.s.joins+msg.u.s.epoints;
|
||||
l = msg.u.s.interfaces+msg.u.s.remotes+msg.u.s.joins+msg.u.s.epoints;
|
||||
ll = l+msg.u.s.ports;
|
||||
while(l < ll)
|
||||
{
|
||||
|
@ -834,7 +834,7 @@ char *admin_state(int sock, char *argv[])
|
|||
i++;
|
||||
anything = 1;
|
||||
}
|
||||
i = 0;
|
||||
i = msg.u.s.interfaces;
|
||||
ii = i + msg.u.s.remotes;
|
||||
while(i < ii)
|
||||
{
|
||||
|
@ -853,7 +853,7 @@ char *admin_state(int sock, char *argv[])
|
|||
if (show_calls == 1)
|
||||
{
|
||||
anything = 0;
|
||||
i = msg.u.s.interfaces+msg.u.s.joins;
|
||||
i = msg.u.s.interfaces+msg.u.s.remotes+msg.u.s.joins;
|
||||
ii = i+msg.u.s.epoints;
|
||||
while(i < ii)
|
||||
{
|
||||
|
@ -892,7 +892,7 @@ char *admin_state(int sock, char *argv[])
|
|||
i++;
|
||||
anything = 1;
|
||||
}
|
||||
j = msg.u.s.interfaces;
|
||||
j = msg.u.s.interfaces+msg.u.s.remotes;
|
||||
jj = j+msg.u.s.joins;
|
||||
while(j < jj)
|
||||
{
|
||||
|
@ -901,7 +901,7 @@ char *admin_state(int sock, char *argv[])
|
|||
color(white);
|
||||
SPRINT(buffer, "(%d):", m[j].u.j.serial);
|
||||
addstr(buffer);
|
||||
i = msg.u.s.interfaces+msg.u.s.joins;
|
||||
i = msg.u.s.interfaces+msg.u.s.remotes+msg.u.s.joins;
|
||||
ii = i+msg.u.s.epoints;
|
||||
while(i < ii)
|
||||
{
|
||||
|
@ -943,7 +943,7 @@ char *admin_state(int sock, char *argv[])
|
|||
{
|
||||
/* show all ports with no epoint */
|
||||
anything = 0;
|
||||
i = msg.u.s.interfaces+msg.u.s.joins+msg.u.s.epoints;
|
||||
i = msg.u.s.interfaces+msg.u.s.remotes+msg.u.s.joins+msg.u.s.epoints;
|
||||
ii = i+msg.u.s.ports;
|
||||
while(i < ii)
|
||||
{
|
||||
|
@ -963,7 +963,7 @@ char *admin_state(int sock, char *argv[])
|
|||
|
||||
/* show all epoints with no call */
|
||||
anything = 0;
|
||||
i = msg.u.s.interfaces+msg.u.s.joins;
|
||||
i = msg.u.s.interfaces+msg.u.s.remotes+msg.u.s.joins;
|
||||
ii = i+msg.u.s.epoints;
|
||||
while(i < ii)
|
||||
{
|
||||
|
@ -983,7 +983,7 @@ char *admin_state(int sock, char *argv[])
|
|||
|
||||
/* show all joins */
|
||||
anything = 0;
|
||||
i = msg.u.s.interfaces;
|
||||
i = msg.u.s.interfaces+msg.u.s.remotes;
|
||||
ii = i+msg.u.s.joins;
|
||||
while(i < ii)
|
||||
{
|
||||
|
|
39
mISDN.h
39
mISDN.h
|
@ -15,18 +15,21 @@
|
|||
extern int entity;
|
||||
extern int mISDNdevice;
|
||||
|
||||
enum {
|
||||
B_EVENT_USE, /* activate/export bchannel */
|
||||
B_EVENT_EXPORTREQUEST, /* remote app requests bchannel */
|
||||
B_EVENT_IMPORTREQUEST, /* remote app releases bchannel */
|
||||
B_EVENT_ACTIVATED, /* DL_ESTABLISH received */
|
||||
B_EVENT_DROP, /* deactivate/re-import bchannel */
|
||||
B_EVENT_DEACTIVATED, /* DL_RELEASE received */
|
||||
B_EVENT_EXPORTED, /* BCHANNEL_ASSIGN received */
|
||||
B_EVENT_IMPORTED, /* BCHANNEL_REMOVE received */
|
||||
B_EVENT_TIMEOUT, /* timeout for bchannel state */
|
||||
};
|
||||
|
||||
/* mISDN port structure list */
|
||||
struct mISDNport {
|
||||
#ifdef SOCKET_MISDN
|
||||
struct mlayer3 *ml3;
|
||||
#else
|
||||
net_stack_t nst; /* MUST be the first entry, so &nst equals &mISDNlist */
|
||||
manager_t mgr;
|
||||
int upper_id; /* id to transfer data down */
|
||||
int lower_id; /* id to transfer data up */
|
||||
int d_stid;
|
||||
msg_queue_t downqueue; /* l4->l3 */
|
||||
#endif
|
||||
struct mISDNport *next;
|
||||
char name[64]; /* name of port, if available */
|
||||
struct interface_port *ifport; /* link to interface_port */
|
||||
|
@ -46,14 +49,8 @@ struct mISDNport {
|
|||
int b_num; /* number of bchannels */
|
||||
int b_reserved; /* number of bchannels reserved or in use */
|
||||
class PmISDN *b_port[128]; /* bchannel assigned to port object */
|
||||
#ifdef SOCKET_MISDN
|
||||
struct mqueue upqueue;
|
||||
int b_socket[128];
|
||||
#else
|
||||
int procids[256]; /* keep track of free ids */
|
||||
int b_stid[128];
|
||||
unsigned long b_addr[128];
|
||||
#endif
|
||||
int b_state[128]; /* statemachine, 0 = IDLE */
|
||||
double b_timer[128]; /* timer for state machine */
|
||||
unsigned long b_remote_id[128]; /* the socket currently exported */
|
||||
|
@ -87,16 +84,8 @@ void mISDNport_close_all(void);
|
|||
void mISDNport_close(struct mISDNport *mISDNport);
|
||||
void mISDN_port_reorder(void);
|
||||
int mISDN_handler(void);
|
||||
#ifdef SOCKET_MISDN
|
||||
void enc_ie_cause_standalone(struct l3_msg *l3m, int location, int cause);
|
||||
int stack2manager(struct mISDNport *mISDNport, unsigned int cmd, unsigned int pid, struct l3_msg *l3m);
|
||||
#else
|
||||
void enc_ie_cause_standalone(unsigned char **ntmode, msg_t *msg, int location, int cause);
|
||||
int stack2manager_te(struct mISDNport *mISDNport, msg_t *msg);
|
||||
int stack2manager_nt(void *dat, void *arg);
|
||||
void setup_queue(struct mISDNport *mISDNport, int link);
|
||||
msg_t *create_l2msg(int prim, int dinfo, int size);
|
||||
#endif
|
||||
void ph_control(struct mISDNport *mISDNport, class PmISDN *isdnport, unsigned long handle, unsigned long c1, unsigned long c2, char *trace_name, int trace_value);
|
||||
void ph_control_block(struct mISDNport *mISDNport, unsigned long handle, unsigned long c1, void *c2, int c2_len, char *trace_name, int trace_value);
|
||||
void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, char *msgtext, int direction);
|
||||
|
@ -111,11 +100,7 @@ class PmISDN : public Port
|
|||
public:
|
||||
PmISDN(int type, struct mISDNport *mISDNport, char *portname, struct port_settings *settings, int channel, int exclusive);
|
||||
~PmISDN();
|
||||
#ifdef SOCKET_MISDN
|
||||
void bchannel_receive(struct mISDNhead *hh, unsigned char *data, int len);
|
||||
#else
|
||||
void bchannel_receive(iframe_t *frm);
|
||||
#endif
|
||||
int handler(void);
|
||||
void transmit(unsigned char *buffer, int length);
|
||||
int message_epoint(unsigned long epoint_id, int message, union parameter *param);
|
||||
|
|
21
main.c
21
main.c
|
@ -26,11 +26,7 @@ struct timezone now_tz;
|
|||
now_tm = localtime(&now); \
|
||||
}
|
||||
|
||||
#ifdef SOCKET_MISDN
|
||||
FILE *debug_fp = NULL;
|
||||
#else
|
||||
int global_debug = 0;
|
||||
#endif
|
||||
int quit=0;
|
||||
|
||||
#if 0
|
||||
|
@ -72,13 +68,8 @@ void debug(const char *function, int line, char *prefix, char *buffer)
|
|||
last_debug = debug_count;
|
||||
if (!nooutput)
|
||||
printf("\033[34m--------------------- %04d.%02d.%02d %02d:%02d:%02d %06d\033[36m\n", now_tm->tm_year+1900, now_tm->tm_mon+1, now_tm->tm_mday, now_tm->tm_hour, now_tm->tm_min, now_tm->tm_sec, debug_count%1000000);
|
||||
#ifdef SOCKET_MISDN
|
||||
if (debug_fp)
|
||||
fprintf(debug_fp, "--------------------- %04d.%02d.%02d %02d:%02d:%02d %06d\n", now_tm->tm_year+1900, now_tm->tm_mon+1, now_tm->tm_mday, now_tm->tm_hour, now_tm->tm_min, now_tm->tm_sec, debug_count%1000000);
|
||||
#else
|
||||
if (options.deb&DEBUG_LOG && global_debug)
|
||||
dprint(DBGM_MAN, 0, "--------------------- %04d.%02d.%02d %02d:%02d:%02d %06d\n", now_tm->tm_year+1900, now_tm->tm_mon+1, now_tm->tm_mday, now_tm->tm_hour, now_tm->tm_min, now_tm->tm_sec, debug_count%1000000);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!nooutput)
|
||||
|
@ -91,26 +82,14 @@ void debug(const char *function, int line, char *prefix, char *buffer)
|
|||
printf("%s", buffer);
|
||||
}
|
||||
|
||||
#ifdef SOCKET_MISDN
|
||||
if (debug_fp)
|
||||
#else
|
||||
if (options.deb&DEBUG_LOG && global_debug)
|
||||
#endif
|
||||
{
|
||||
if (debug_newline)
|
||||
{
|
||||
if (function)
|
||||
#ifdef SOCKET_MISDN
|
||||
fprintf(debug_fp, "%s%s(in %s() line %d): %s", prefix?prefix:"", prefix?" ":"", function, line, buffer);
|
||||
#else
|
||||
dprint(DBGM_MAN, 0, "%s%s(in %s() line %d): %s", prefix?prefix:"", prefix?" ":"", function, line, buffer);
|
||||
#endif
|
||||
else
|
||||
#ifdef SOCKET_MISDN
|
||||
fprintf(debug_fp, "%s%s: %s", prefix?prefix:"", prefix?" ":"", buffer);
|
||||
#else
|
||||
dprint(DBGM_MAN, 0, "%s%s: %s", prefix?prefix:"", prefix?" ":"", buffer);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
11
main.h
11
main.h
|
@ -34,7 +34,7 @@
|
|||
|
||||
#define DEFAULT_ENDPOINT_APP EndpointAppPBX
|
||||
|
||||
#define VERSION_STRING "0.5 (Spring 2007)"
|
||||
#define VERSION_STRING "1.0 beta 1 (Summer 2008)"
|
||||
|
||||
extern int memuse;
|
||||
extern int mmemuse;
|
||||
|
@ -49,11 +49,7 @@ extern int fhuse;
|
|||
|
||||
//extern pthread_mutex_t mutex_lcr; // lcr process mutex
|
||||
|
||||
#ifdef SOCKET_MISDN
|
||||
extern FILE *debug_fp;
|
||||
#else
|
||||
extern int global_debug;
|
||||
#endif
|
||||
|
||||
#define PDEBUG(mask, fmt, arg...) _printdebug(__FUNCTION__, __LINE__, mask, fmt, ## arg)
|
||||
#define PERROR(fmt, arg...) _printerror(__FUNCTION__, __LINE__, fmt, ## arg)
|
||||
|
@ -133,12 +129,7 @@ void debug(const char *function, int line, char *prefix, char *buffer);
|
|||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#ifndef SOCKET_MISDN
|
||||
#include <mISDNuser/isdn_net.h>
|
||||
#include <mISDNuser/net_l3.h>
|
||||
#else
|
||||
#include <mbuffer.h>
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
11
message.h
11
message.h
|
@ -129,6 +129,7 @@ enum { /* isdnsignal */
|
|||
|
||||
enum { /* bchannel assignment */
|
||||
BCHANNEL_REQUEST, /* application requests bchannel */
|
||||
BCHANNEL_RELEASE, /* application releases bchannel */
|
||||
BCHANNEL_ASSIGN, /* bchannel assigned by LCR */
|
||||
BCHANNEL_ASSIGN_ACK, /* application acknowledges */
|
||||
BCHANNEL_REMOVE, /* bchannel removed by LCR */
|
||||
|
@ -143,16 +144,6 @@ enum {
|
|||
B_STATE_REMOTE, /* bchannel assigned to remote application */
|
||||
B_STATE_IMPORTING, /* BCHANNEL_REMOVE sent */
|
||||
};
|
||||
enum {
|
||||
B_EVENT_USE, /* activate/export bchannel */
|
||||
B_EVENT_EXPORTREQUEST, /* remote app requests bchannel */
|
||||
B_EVENT_ACTIVATED, /* DL_ESTABLISH received */
|
||||
B_EVENT_DROP, /* deactivate/re-import bchannel */
|
||||
B_EVENT_DEACTIVATED, /* DL_RELEASE received */
|
||||
B_EVENT_EXPORTED, /* BCHANNEL_ASSIGN received */
|
||||
B_EVENT_IMPORTED, /* BCHANNEL_REMOVE received */
|
||||
B_EVENT_TIMEOUT, /* timeout for bchannel state */
|
||||
};
|
||||
|
||||
/* call-info structure CALLER */
|
||||
struct caller_info {
|
||||
|
|
4
myisdn.h
4
myisdn.h
|
@ -10,8 +10,6 @@
|
|||
\*****************************************************************************/
|
||||
|
||||
|
||||
#ifndef SOCKET_MISDN
|
||||
|
||||
#define MT_ALERTING 0x01
|
||||
#define MT_CALL_PROCEEDING 0x02
|
||||
#define MT_CONNECT 0x07
|
||||
|
@ -88,8 +86,6 @@
|
|||
#define IE_CONGESTION 0xb0
|
||||
#define IE_REPEAT 0xd0
|
||||
|
||||
#endif
|
||||
|
||||
#define CENTREX_FAC 0x88
|
||||
#define CENTREX_ID 0xa1
|
||||
|
||||
|
|
4
route.c
4
route.c
|
@ -232,8 +232,8 @@ struct param_defs param_defs[] = {
|
|||
"application",PARAM_TYPE_STRING,
|
||||
"application=<name>", "Name of remote application to make call to."},
|
||||
{ PARAM_CONTEXT,
|
||||
"exten", PARAM_TYPE_STRING,
|
||||
"exten=<extension>", "Give context parameter to the remote application."},
|
||||
"context", PARAM_TYPE_STRING,
|
||||
"context=<context>", "Give context parameter to the remote application."},
|
||||
{ PARAM_EXTEN,
|
||||
"exten", PARAM_TYPE_STRING,
|
||||
"exten=<extension>", "Give exten parameter to the remote application. (overrides dialed number)"},
|
||||
|
|
|
@ -84,6 +84,16 @@ void free_connection(struct admin_list *admin)
|
|||
/* free remote joins */
|
||||
if (admin->remote_name[0])
|
||||
{
|
||||
start_trace(0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
DIRECTION_NONE,
|
||||
0,
|
||||
0,
|
||||
"REMOTE APP release");
|
||||
add_trace("app", "name", "%s", admin->remote_name);
|
||||
end_trace();
|
||||
join = join_first;
|
||||
while(join)
|
||||
{
|
||||
|
@ -579,39 +589,49 @@ void admin_call_response(int adminid, int message, char *connected, int cause, i
|
|||
/*
|
||||
* send data to the remote socket join instance
|
||||
*/
|
||||
int admin_message_to_join(struct admin_msg *msg, char *remote_name, int sock_id)
|
||||
int admin_message_to_join(struct admin_msg *msg, struct admin_list *admin)
|
||||
{
|
||||
class Join *join;
|
||||
struct admin_list *admin;
|
||||
struct admin_list *temp;
|
||||
|
||||
/* hello message */
|
||||
if (msg->type == MESSAGE_HELLO)
|
||||
{
|
||||
if (remote_name[0])
|
||||
if (admin->remote_name[0])
|
||||
{
|
||||
PERROR("Remote application repeats hello message.\n");
|
||||
return(-1);
|
||||
}
|
||||
/* look for second application */
|
||||
admin = admin_first;
|
||||
while(admin)
|
||||
temp = admin_first;
|
||||
while(temp)
|
||||
{
|
||||
if (!strcmp(admin->remote_name, msg->param.hello.application))
|
||||
if (!strcmp(temp->remote_name, msg->param.hello.application))
|
||||
break;
|
||||
admin = admin->next;
|
||||
temp = temp->next;
|
||||
}
|
||||
if (admin)
|
||||
if (temp)
|
||||
{
|
||||
PERROR("Remote application connects twice??? (ignoring)\n");
|
||||
return(-1);
|
||||
}
|
||||
/* set remote socket instance */
|
||||
SCPY(remote_name, msg->param.hello.application);
|
||||
SCPY(admin->remote_name, msg->param.hello.application);
|
||||
start_trace(0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
DIRECTION_NONE,
|
||||
0,
|
||||
0,
|
||||
"REMOTE APP registers");
|
||||
add_trace("app", "name", "%s", admin->remote_name);
|
||||
end_trace();
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* check we have no application name */
|
||||
if (remote_name[0])
|
||||
if (!admin->remote_name[0])
|
||||
{
|
||||
PERROR("Remote application did not send us a hello message.\n");
|
||||
return(-1);
|
||||
|
@ -621,9 +641,12 @@ int admin_message_to_join(struct admin_msg *msg, char *remote_name, int sock_id)
|
|||
if (msg->type == MESSAGE_NEWREF)
|
||||
{
|
||||
/* create new join instance */
|
||||
join = new JoinRemote(0, remote_name, sock_id); // must have no serial, because no endpoint is connected
|
||||
join = new JoinRemote(0, admin->remote_name, admin->sock); // must have no serial, because no endpoint is connected
|
||||
if (!join)
|
||||
{
|
||||
FATAL("No memory for remote join instance\n");
|
||||
return(-1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
@ -665,9 +688,9 @@ int admin_message_to_join(struct admin_msg *msg, char *remote_name, int sock_id)
|
|||
PERROR("Ref %d does not belong to a remote join instance.\n", msg->ref);
|
||||
return(-1);
|
||||
}
|
||||
if (sock_id != ((class JoinRemote *)join)->j_remote_id)
|
||||
if (admin->sock != ((class JoinRemote *)join)->j_remote_id)
|
||||
{
|
||||
PERROR("Ref %d belongs to remote application %s, but not to sending application %s.\n", msg->ref, ((class JoinRemote *)join)->j_remote_name, remote_name);
|
||||
PERROR("Ref %d belongs to remote application %s, but not to sending application %s.\n", msg->ref, ((class JoinRemote *)join)->j_remote_name, admin->remote_name);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
@ -684,7 +707,7 @@ int admin_message_to_join(struct admin_msg *msg, char *remote_name, int sock_id)
|
|||
int admin_message_from_join(int remote_id, unsigned long ref, int message_type, union parameter *param)
|
||||
{
|
||||
struct admin_list *admin;
|
||||
struct admin_queue *response, **responsep; /* response pointer */
|
||||
struct admin_queue **responsep; /* response pointer */
|
||||
|
||||
/* searching for admin id
|
||||
* maybe there is no given remote application
|
||||
|
@ -701,27 +724,22 @@ int admin_message_from_join(int remote_id, unsigned long ref, int message_type,
|
|||
return(-1);
|
||||
|
||||
/* seek to end of response list */
|
||||
response = admin->response;
|
||||
responsep = &admin->response;
|
||||
while(response)
|
||||
while(*responsep)
|
||||
{
|
||||
responsep = &response->next;
|
||||
response = response->next;
|
||||
responsep = &(*responsep)->next;
|
||||
}
|
||||
|
||||
/* create state response */
|
||||
response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
|
||||
*responsep = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
|
||||
memuse++;
|
||||
response->num = 1;
|
||||
(*responsep)->num = 1;
|
||||
|
||||
/* message */
|
||||
response->am[0].u.msg.type = message_type;
|
||||
response->am[0].u.msg.ref = ref;
|
||||
memcpy(&response->am[0].u.msg.param, param, sizeof(union parameter));
|
||||
|
||||
/* attach to response chain */
|
||||
*responsep = response;
|
||||
responsep = &response->next;
|
||||
(*responsep)->am[0].message = ADMIN_MESSAGE;
|
||||
(*responsep)->am[0].u.msg.type = message_type;
|
||||
(*responsep)->am[0].u.msg.ref = ref;
|
||||
memcpy(&(*responsep)->am[0].u.msg.param, param, sizeof(union parameter));
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
@ -813,8 +831,12 @@ int admin_state(struct admin_queue **responsep)
|
|||
*responsep = response;
|
||||
responsep = &response->next;
|
||||
|
||||
/* create response for all interfaces */
|
||||
num = (response->am[0].u.s.interfaces)+(response->am[0].u.s.joins)+(response->am[0].u.s.epoints)+(response->am[0].u.s.ports);
|
||||
/* create response for all instances */
|
||||
num = (response->am[0].u.s.interfaces)
|
||||
+ (response->am[0].u.s.remotes)
|
||||
+ (response->am[0].u.s.joins)
|
||||
+ (response->am[0].u.s.epoints)
|
||||
+ (response->am[0].u.s.ports);
|
||||
if (num == 0)
|
||||
return(0);
|
||||
response = (struct admin_queue *)MALLOC(sizeof(admin_queue)+(num*sizeof(admin_message)));
|
||||
|
@ -1169,7 +1191,7 @@ int admin_handle(void)
|
|||
continue;
|
||||
}
|
||||
/* process socket command */
|
||||
if (admin->response)
|
||||
if (admin->response && msg.message != ADMIN_MESSAGE)
|
||||
{
|
||||
PERROR("Data from socket %d while sending response.\n", admin->sock);
|
||||
*adminp = admin->next;
|
||||
|
@ -1236,7 +1258,7 @@ int admin_handle(void)
|
|||
break;
|
||||
|
||||
case ADMIN_MESSAGE:
|
||||
if (admin_message_to_join(&msg.u.msg, admin->remote_name, admin->sock) < 0)
|
||||
if (admin_message_to_join(&msg.u.msg, admin) < 0)
|
||||
{
|
||||
PERROR("Failed to deliver message for socket %d.\n", admin->sock);
|
||||
goto response_error;
|
||||
|
@ -1295,7 +1317,7 @@ int admin_handle(void)
|
|||
work = 1;
|
||||
if (len == 0)
|
||||
goto end;
|
||||
if (len < (int)(sizeof(struct admin_message)*(admin->response->num)-admin->response->offset))
|
||||
if (len < (int)(sizeof(struct admin_message)*(admin->response->num) - admin->response->offset))
|
||||
{
|
||||
admin->response->offset+=len;
|
||||
goto next;
|
||||
|
|
7
trace.h
7
trace.h
|
@ -91,17 +91,10 @@
|
|||
#define L3_RETRIEVE_ACKNOWLEDGE_IND 0x00033302
|
||||
#define L3_RETRIEVE_REJECT_REQ 0x00033700
|
||||
#define L3_RETRIEVE_REJECT_IND 0x00033702
|
||||
#ifdef SOCKET_MISDN
|
||||
#define L3_NEW_L3ID_REQ 0x0003f000
|
||||
#define L3_NEW_L3ID_IND 0x0003f002
|
||||
#define L3_RELEASE_L3ID_REQ 0x0003f100
|
||||
#define L3_RELEASE_L3ID_IND 0x0003f102
|
||||
#else
|
||||
#define L3_NEW_CR_REQ 0x0003f000
|
||||
#define L3_NEW_CR_IND 0x0003f002
|
||||
#define L3_RELEASE_CR_REQ 0x0003f100
|
||||
#define L3_RELEASE_CR_IND 0x0003f102
|
||||
#endif
|
||||
#define L3_TIMEOUT_REQ 0x0003f200
|
||||
#define L3_TIMEOUT_IND 0x0003f202
|
||||
#define L3_UNKNOWN 0x0003ff00
|
||||
|
|
Loading…
Reference in New Issue