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:
Super User 2008-06-01 18:52:10 +02:00
parent 29506a890c
commit 026b04fc75
28 changed files with 639 additions and 4293 deletions

View File

@ -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)

View File

@ -1,3 +1,5 @@
OUTDATED!!!! must be rewritten! see Makefile
## Makefile.am -- Process this file with automake to produce Makefile.in

10
README
View File

@ -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.

View File

@ -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);
}
}
}

View File

@ -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 */
}

View File

@ -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)
{

View File

@ -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;

View File

@ -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;

View File

@ -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*/

View File

@ -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, &param->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, &param);
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(&param, 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,
);

View File

@ -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];

View File

@ -1,3 +1,5 @@
OUTDATED, please update
## -*- autoconf -*-
dnl This file is part of linux-call-router

View File

@ -1,4 +1,4 @@
# PBX4Linux routing configuration "routing.conf"
# Linux-Call-Router routing configuration "routing.conf"
# Ruleset: MAIN

1510
dss1.cpp

File diff suppressed because it is too large Load Diff

65
dss1.h
View File

@ -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
View File

@ -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");

585
ie.cpp

File diff suppressed because it is too large Load Diff

View File

@ -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",

View File

@ -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)
{

1476
mISDN.cpp

File diff suppressed because it is too large Load Diff

39
mISDN.h
View File

@ -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
View File

@ -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
View File

@ -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

View File

@ -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 {

View File

@ -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

View File

@ -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)"},

View File

@ -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;

View File

@ -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