summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile8
-rw-r--r--README3
-rw-r--r--action.cpp102
-rw-r--r--admin.h8
-rw-r--r--admin_client.c35
-rw-r--r--admin_server.c153
-rw-r--r--admin_server.h6
-rw-r--r--apppbx.cpp132
-rw-r--r--apppbx.h6
-rw-r--r--asterisk_client.c26
-rw-r--r--channel.c257
-rw-r--r--default/interface.conf20
-rw-r--r--default/routing.conf2
-rw-r--r--dss1.cpp8
-rw-r--r--dss1.h2
-rw-r--r--interface.c6
-rw-r--r--join.cpp8
-rw-r--r--join.h6
-rw-r--r--joinpbx.cpp178
-rw-r--r--joinpbx.h18
-rw-r--r--joinremote.cpp (renamed from joinasterisk.cpp)41
-rw-r--r--joinremote.h (renamed from joinasterisk.h)11
-rw-r--r--mISDN.cpp56
-rw-r--r--main.h2
-rw-r--r--message.h17
-rw-r--r--route.c35
-rw-r--r--route.h9
-rw-r--r--todo.txt14
-rw-r--r--trace.c2
29 files changed, 817 insertions, 354 deletions
diff --git a/Makefile b/Makefile
index 71220e8..3fbf24b 100644
--- a/Makefile
+++ b/Makefile
@@ -130,8 +130,8 @@ join.o: join.cpp *.h Makefile
joinpbx.o: joinpbx.cpp *.h Makefile
$(CC) -c $(CFLAGS) joinpbx.cpp -o joinpbx.o
-joinasterisk.o: joinasterisk.cpp *.h Makefile
- $(CC) -c $(CFLAGS) joinasterisk.cpp -o joinasterisk.o
+joinremote.o: joinremote.cpp *.h Makefile
+ $(CC) -c $(CFLAGS) joinremote.cpp -o joinremote.o
cause.o: cause.c *.h Makefile
$(CC) -c $(CFLAGS) cause.c -o cause.o
@@ -182,7 +182,7 @@ $(LCR): main.o \
mail.o \
join.o \
joinpbx.o \
- joinasterisk.o \
+ joinremote.o \
admin_server.o \
trace.o
$(LD) $(LIBDIR) \
@@ -209,7 +209,7 @@ $(LCR): main.o \
mail.o \
join.o \
joinpbx.o \
- joinasterisk.o \
+ joinremote.o \
admin_server.o \
trace.o \
$(LIBS) -o $(LCR)
diff --git a/README b/README
index 88994df..32193ca 100644
--- a/README
+++ b/README
@@ -351,7 +351,6 @@ Changes in Version 1.0
- Layer 1 over IP supports interconnection via IP
- Rebuild line and b-channel hunting with individual lists
- Screen lists for changing caller IDs
-- Asterisk channel driver integrated
- Multiplexing calls to multiple extensions
- Removed all VoIP stuff to make core fast and stable (Use Asterisk for VoIP.)
- Fixed a bug that caused some isdn connections to hang during disconnect
@@ -359,4 +358,6 @@ Changes in Version 1.0
- Many minor improvements
- New bugs of course...
- Rename of 'Call' instances to 'Join', because they join parties together.
+- A new remote interface for external applications is integrated
+ -> Our first application is (-: *ASTERISK CHANNEL DRIVER* :-)
diff --git a/action.cpp b/action.cpp
index d253679..d0dbf8d 100644
--- a/action.cpp
+++ b/action.cpp
@@ -67,9 +67,9 @@ char *numberrize_callerinfo(char *string, int ntype)
/*
- * process init 'internal' / 'external' / 'asterisk' / 'vbox-record' / 'partyline'...
+ * process init 'internal' / 'external' / 'remote' / 'vbox-record' / 'partyline'...
*/
-void EndpointAppPBX::_action_init_call(int asterisk)
+void EndpointAppPBX::_action_init_call(char *remote)
{
class Join *join;
struct port_list *portlist = ea_endpoint->ep_portlist;
@@ -83,40 +83,80 @@ void EndpointAppPBX::_action_init_call(int asterisk)
return;
}
- /* create call */
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d): Creating new call instance.\n", ea_endpoint->ep_serial);
- if (asterisk)
+ /* create join */
+ PDEBUG(DEBUG_EPOINT, "EPOINT(%d): Creating new join instance.\n", ea_endpoint->ep_serial);
+ if (remote)
{
- admin = admin_list;
+ admin = admin_first;
while(admin)
{
- if (admin->asterisk)
+ if (admin->remote[0] && !strcmp(admin->remote, remote))
break;
admin = admin->next;
}
if (!admin)
{
/* resource not available */
+ 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, "");
new_state(EPOINT_STATE_OUT_DISCONNECT);
set_tone(portlist,"cause_22");
return;
}
- join = new JoinAsterisk(ea_endpoint->ep_serial);
+ join = new JoinRemote(ea_endpoint->ep_serial, remote);
}
else
join = new JoinPBX(ea_endpoint);
if (!join)
- FATAL("No memoy for Call instance.\n");
- ea_endpoint->ep_join_id = join->c_serial;
+ FATAL("No memoy for Join instance.\n");
+ ea_endpoint->ep_join_id = join->j_serial;
}
void EndpointAppPBX::action_init_call(void)
{
- _action_init_call(0);
+ _action_init_call(NULL);
}
-void EndpointAppPBX::action_init_chan(void)
+void EndpointAppPBX::action_init_remote(void)
{
- _action_init_call(1);
+ struct route_param *rparam;
+ struct port_list *portlist = ea_endpoint->ep_portlist;
+ struct message *message;
+ struct capa_info capainfo;
+ struct caller_info callerinfo;
+ struct redir_info redirinfo;
+ struct dialing_info dialinginfo;
+ 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));
+
+ /* send setup to remote */
+ trace_header("ACTION remote (setup)", DIRECTION_NONE);
+ add_trace("number", NULL, dialinginfo.id);
+ add_trace("remote", NULL, remote);
+ 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));
+ message_put(message);
}
/*
@@ -394,15 +434,25 @@ void EndpointAppPBX::action_dialing_external(void)
}
-void EndpointAppPBX::action_dialing_chan(void)
+void EndpointAppPBX::action_dialing_remote(void)
{
- struct port_list *portlist = ea_endpoint->ep_portlist;
+ struct message *message;
+ struct dialing_info dialinginfo;
+// struct route_param *rparam;
- trace_header("ACTION channel (not implemented)", DIRECTION_NONE);
- end_trace();
- message_disconnect_port(portlist, CAUSE_UNIMPLEMENTED, LOCATION_PRIVATE_LOCAL, "");
- new_state(EPOINT_STATE_OUT_DISCONNECT);
- set_tone(portlist,"cause_4f");
+ /* create bearer/caller/dialinginfo */
+ memset(&dialinginfo, 0, sizeof(dialinginfo));
+
+ if (dialinginfo.id[0])
+ {
+ /* add or update outgoing call */
+ trace_header("ACTION remote (dialing)", DIRECTION_NONE);
+ add_trace("number", NULL, dialinginfo.id);
+ 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_put(message);
+ }
}
@@ -526,10 +576,10 @@ void EndpointAppPBX::action_init_partyline(void)
join = join_first;
while(join)
{
- if (join->c_type == JOIN_TYPE_PBX)
+ if (join->j_type == JOIN_TYPE_PBX)
{
joinpbx = (class JoinPBX *)join;
- if (joinpbx->c_partyline == rparam->integer_value)
+ if (joinpbx->j_partyline == rparam->integer_value)
break;
}
join = join->next;
@@ -553,7 +603,7 @@ void EndpointAppPBX::action_init_partyline(void)
relation->epoint_id = ea_endpoint->ep_serial;
}
- ea_endpoint->ep_join_id = join->c_serial;
+ ea_endpoint->ep_join_id = join->j_serial;
set_tone(portlist, "proceeding");
message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_PROCEEDING);
@@ -2318,10 +2368,10 @@ void EndpointAppPBX::process_dialing(void)
goto process_action;
}
/* check for chan call */
- if (!strncmp(e_dialinginfo.id, "chan:", 5))
+ if (!strncmp(e_dialinginfo.id, "remote:", 7))
{
- e_extdialing = e_dialinginfo.id+4;
- e_action = &action_chan;
+ e_extdialing = e_dialinginfo.id+7;
+ e_action = &action_remote;
goto process_action;
}
/* check for vbox call */
diff --git a/admin.h b/admin.h
index 70b21aa..a34820d 100644
--- a/admin.h
+++ b/admin.h
@@ -26,6 +26,7 @@ enum { /* messages */
ADMIN_RESPONSE_CMD_BLOCK,
ADMIN_REQUEST_STATE,
ADMIN_RESPONSE_STATE,
+ ADMIN_RESPONSE_S_REMOTE,
ADMIN_RESPONSE_S_INTERFACE,
ADMIN_RESPONSE_S_PORT,
ADMIN_RESPONSE_S_EPOINT,
@@ -55,6 +56,7 @@ struct admin_response_state {
struct tm tm;
char logfile[128];
int interfaces;
+ int remotes;
int joins;
int epoints;
int ports;
@@ -76,8 +78,13 @@ struct admin_response_interface {
unsigned long port[256]; /* current port */
};
+struct admin_response_remote {
+ char name[32]; /* name of remote application */
+};
+
struct admin_response_join {
unsigned long serial; /* join serial number */
+ char remote[32]; /* remote application name */
unsigned long partyline;
};
@@ -153,6 +160,7 @@ struct admin_message {
struct admin_response_port p;
struct admin_response_epoint e;
struct admin_response_join j;
+ struct admin_response_remote r;
struct admin_call call;
struct admin_msg msg;
struct admin_trace_req trace_req;
diff --git a/admin_client.c b/admin_client.c
index a7e7f52..02624a0 100644
--- a/admin_client.c
+++ b/admin_client.c
@@ -405,6 +405,14 @@ int debug_join(struct admin_message *msg, struct admin_message *m, int line, int
SPRINT(buffer, "%d\n", m[i].u.j.partyline);
addstr(buffer);
}
+ if (m[i].u.j.remote[0])
+ {
+ color(cyan);
+ addstr(" remote=");
+ color(white);
+ SPRINT(buffer, "%s\n", m[i].u.j.remote);
+ addstr(buffer);
+ }
/* find number of epoints */
j = msg->u.s.interfaces+msg->u.s.joins;
jj = j + msg->u.s.epoints;
@@ -485,7 +493,7 @@ char *admin_state(int sock, char *argv[])
cleanup_curses();
return("Response not valid. Expecting state response.");
}
- num = msg.u.s.interfaces + msg.u.s.joins + msg.u.s.epoints + msg.u.s.ports;
+ num = msg.u.s.interfaces + msg.u.s.remotes + msg.u.s.joins + msg.u.s.epoints + msg.u.s.ports;
m = (struct admin_message *)MALLOC(num*sizeof(struct admin_message));
off=0;
if (num)
@@ -522,13 +530,25 @@ char *admin_state(int sock, char *argv[])
j++;
}
i = 0;
+ while(i < msg.u.s.remotes)
+ {
+ if (m[j].message != ADMIN_RESPONSE_S_REMOTE)
+ {
+ FREE(m, 0);
+ cleanup_curses();
+ return("Response not valid. Expecting remote application information.");
+ }
+ i++;
+ j++;
+ }
+ i = 0;
while(i < msg.u.s.joins)
{
if (m[j].message != ADMIN_RESPONSE_S_JOIN)
{
FREE(m, 0);
cleanup_curses();
- return("Response not valid. Expecting call information.");
+ return("Response not valid. Expecting join information.");
}
i++;
j++;
@@ -763,6 +783,17 @@ char *admin_state(int sock, char *argv[])
i++;
anything = 1;
}
+ i = 0;
+ ii = i + msg.u.s.remotes;
+ while(i < ii)
+ {
+ /* show remote summary */
+ move(++line>1?line:1, 0);
+ color(white);
+ SPRINT(buffer, "Remote: %s", m[i].u.r.name);
+ addstr(buffer);
+ i++;
+ }
if (anything)
line++;
if (line+2 >= LINES) goto end;
diff --git a/admin_server.c b/admin_server.c
index 1176118..6292e12 100644
--- a/admin_server.c
+++ b/admin_server.c
@@ -33,7 +33,7 @@ char *socket_name = SOCKET_NAME;
int sock = -1;
struct sockaddr_un sock_address;
-struct admin_list *admin_list = NULL;
+struct admin_list *admin_first = NULL;
/*
* initialize admin socket
@@ -86,7 +86,7 @@ int admin_init(void)
/*
* free connection
- * also releases all asterisk joins
+ * also releases all remote joins
*/
void free_connection(struct admin_list *admin)
{
@@ -95,19 +95,19 @@ void free_connection(struct admin_list *admin)
union parameter param;
class Join *join, *joinnext;
- /* free asterisk joins */
- if (admin->asterisk)
+ /* free remote joins */
+ if (admin->remote[0])
{
join = join_first;
while(join)
{
joinnext = join->next;
- if (join->c_type == JOIN_TYPE_ASTERISK)
+ if (join->j_type==JOIN_TYPE_REMOTE && !strcmp(((class JoinRemote *)join)->j_remote, admin->remote))
{
memset(&param, 0, sizeof(param));
param.disconnectinfo.cause = CAUSE_OUTOFORDER;
param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
- ((class JoinAsterisk *)join)->message_asterisk(0, MESSAGE_RELEASE, &param);
+ ((class JoinRemote *)join)->message_remote(0, MESSAGE_RELEASE, &param);
/* join is now destroyed, so we go to next join */
}
join = joinnext;
@@ -144,7 +144,7 @@ void admin_cleanup(void)
{
struct admin_list *admin, *next;;
- admin = admin_list;
+ admin = admin_first;
while(admin)
{
//printf("clean\n");
@@ -255,8 +255,8 @@ int admin_route(struct admin_queue **responsep)
case ACTION_EXTERNAL:
apppbx->e_action = &action_external;
break;
- case ACTION_CHAN:
- apppbx->e_action = &action_chan;
+ case ACTION_REMOTE:
+ apppbx->e_action = &action_remote;
break;
case ACTION_VBOX_RECORD:
apppbx->e_action = &action_vbox;
@@ -552,7 +552,7 @@ void admin_call_response(int adminid, int message, char *connected, int cause, i
/* searching for admin id
* maybe there is no admin instance, because the calling port was not
* initiated by admin_call */
- admin = admin_list;
+ admin = admin_first;
while(admin)
{
if (adminid == admin->sockserial)
@@ -591,85 +591,110 @@ void admin_call_response(int adminid, int message, char *connected, int cause, i
/*
- * send data to the asterisk join instance
+ * send data to the remote socket join instance
*/
-int admin_message_to_join(struct admin_msg *msg)
+int admin_message_to_join(struct admin_msg *msg, char *remote)
{
class Join *join;
struct admin_list *admin;
- /* dummy callref means: asterisk is here */
+ /* hello message */
if (msg->type == MESSAGE_HELLO)
{
- /* look for second asterisk */
- admin = admin_list;
+ if (remote[0])
+ {
+ PERROR("Remote application repeats hello message.\n");
+ return(-1);
+ }
+ /* look for second application */
+ admin = admin_first;
while(admin)
{
- if (admin->asterisk)
+ if (!strcmp(admin->remote, msg->param.hello.application))
break;
admin = admin->next;
}
if (admin)
{
- PERROR("Asterisk connects twice??? (ignoring)\n");
+ PERROR("Remote application connects twice??? (ignoring)\n");
return(-1);
}
/* set asterisk socket instance */
- admin->asterisk = 1;
+ SCPY(remote, msg->param.hello.application);
+ return(0);
+ }
+
+ /* check we already have no application name */
+ if (!remote[0])
+ {
+ PERROR("Remote application did not send us a hello message.\n");
+ return(-1);
+ }
+
+ /* new join */
+ if (msg->type == MESSAGE_NEWREF)
+ {
+ /* create new join instance */
+ join = new JoinRemote(0, remote); // must have no serial, because no endpoint is connected
+ if (!join)
+ FATAL("No memory for remote join instance\n");
+ return(0);
+ }
+
+ /* check for ref */
+ if (!msg->ref)
+ {
+ PERROR("Remote application did not send us a valid ref with a message.\n");
+ return(-1);
}
/* find join instance */
join = join_first;
while(join)
{
- if (join->c_serial == msg->ref)
+ if (join->j_serial == msg->ref)
break;
join = join->next;
}
- /* create join instance if not existing */
- if (!join)
+ /* check application */
+ if (join->j_type != JOIN_TYPE_REMOTE)
{
- if (msg->ref < 2000000000)
- {
- PERROR("Asterisk sends us unknown ref %d below 2000000000.\n", msg->ref);
- return(-1);
- }
-
- /* create new join instance */
- join = new JoinAsterisk(0); // must have no serial, because no endpoint is connected
- if (!join)
- FATAL("No memory for Asterisk join instance\n");
+ PERROR("Ref %d does not belong to a remote join instance.\n", msg->ref);
+ return(-1);
+ }
+ if (!!strcmp(remote, ((class JoinRemote *)join)->j_remote))
+ {
+ PERROR("Ref %d belongs to remote application %s, but not to sending application %s.\n", msg->ref, ((class JoinRemote *)join)->j_remote, remote);
+ return(-1);
}
/* send message */
- if (join->c_type != JOIN_TYPE_ASTERISK)
- FATAL("join instance %d must be of type join Asterisk\n", join->c_serial);
- ((class JoinAsterisk *)join)->message_asterisk(msg->ref, msg->type, &msg->param);
+ ((class JoinRemote *)join)->message_remote(msg->ref, msg->type, &msg->param);
return(0);
}
/*
- * this function is called for every message to asterisk
+ * this function is called for every message to remote socket
*/
-int admin_message_from_join(unsigned long ref, int message_type, union parameter *param)
+int admin_message_from_join(char *remote, unsigned long ref, int message_type, union parameter *param)
{
struct admin_list *admin;
struct admin_queue *response, **responsep; /* response pointer */
/* searching for admin id
- * maybe there is no asterisk instance
+ * maybe there is no given remote application
*/
- admin = admin_list;
+ admin = admin_first;
while(admin)
{
- if (admin->asterisk)
+ if (admin->remote[0] && !strcmp(admin->remote, remote))
break;
admin = admin->next;
}
- /* no asterisk connected */
+ /* no given remote application connected */
if (!admin)
return(-1);
@@ -717,6 +742,7 @@ int admin_state(struct admin_queue **responsep)
int num;
int anybusy;
struct admin_queue *response;
+ struct admin_list *admin;
/* create state response */
response = (struct admin_queue *)MALLOC(sizeof(struct admin_queue)+sizeof(admin_message));
@@ -744,6 +770,16 @@ int admin_state(struct admin_queue **responsep)
interface = interface->next;
}
response->am[0].u.s.interfaces = i;
+ /* remote connection count */
+ i = 0;
+ admin = admin_first;
+ while(admin)
+ {
+ if (admin->remote[0])
+ i++;
+ admin = admin->next;
+ }
+ response->am[0].u.s.remotes = i;
/* join count */
join = join_first;
i = 0;
@@ -837,6 +873,22 @@ int admin_state(struct admin_queue **responsep)
interface = interface->next;
}
+ /* create response for all remotes */
+ admin = admin_first;
+ while(admin)
+ {
+ if (admin->remote[0])
+ {
+ /* message */
+ response->am[num].message = ADMIN_RESPONSE_S_REMOTE;
+ /* name */
+ SCPY(response->am[num].u.r.name, admin->remote);
+ /* */
+ num++;
+ }
+ admin = admin->next;
+ }
+
/* create response for all joins */
join = join_first;
while(join)
@@ -844,10 +896,13 @@ int admin_state(struct admin_queue **responsep)
/* message */
response->am[num].message = ADMIN_RESPONSE_S_JOIN;
/* serial */
- response->am[num].u.j.serial = join->c_serial;
+ response->am[num].u.j.serial = join->j_serial;
/* partyline */
- if (join->c_type == JOIN_TYPE_PBX)
- response->am[num].u.j.partyline = ((class JoinPBX *)join)->c_partyline;
+ if (join->j_type == JOIN_TYPE_PBX)
+ response->am[num].u.j.partyline = ((class JoinPBX *)join)->j_partyline;
+ /* remote application */
+ if (join->j_type == JOIN_TYPE_REMOTE)
+ SCPY(response->am[num].u.j.remote, ((class JoinRemote *)join)->j_remote);
/* */
join = join->next;
num++;
@@ -1029,8 +1084,8 @@ int admin_handle(void)
memuse++;
fhuse++;
admin->sockserial = sockserial++;
- admin->next = admin_list;
- admin_list = admin;
+ admin->next = admin_first;
+ admin_first = admin;
admin->sock = new_sock;
} else {
close(new_sock);
@@ -1047,8 +1102,8 @@ int admin_handle(void)
}
/* loop all current socket connections */
- admin = admin_list;
- adminp = &admin_list;
+ admin = admin_first;
+ adminp = &admin_first;
while(admin)
{
/* read command */
@@ -1091,7 +1146,7 @@ int admin_handle(void)
*adminp = admin->next;
free_connection(admin);
admin = *adminp;
-//PERROR("DEBUG (admin_list=%x)\n", admin_list);
+//PERROR("DEBUG (admin_first=%x)\n", admin_first);
continue;
}
if (len != sizeof(msg))
@@ -1170,7 +1225,7 @@ int admin_handle(void)
break;
case ADMIN_MESSAGE:
- if (admin_message_to_join(&msg.u.msg) < 0)
+ if (admin_message_to_join(&msg.u.msg, admin->remote) < 0)
{
PERROR("Failed to deliver message for socket %d.\n", admin->sock);
goto response_error;
diff --git a/admin_server.h b/admin_server.h
index d83c451..2351298 100644
--- a/admin_server.h
+++ b/admin_server.h
@@ -22,19 +22,19 @@ struct admin_list {
struct admin_list *next;
int sock;
int sockserial;
- int asterisk; /* socket is connected to asterisk */
+ char remote[32]; /* socket is connected remote application */
struct admin_trace_req trace; /* stores trace, if detail != 0 */
unsigned long epointid;
struct admin_queue *response;
};
-extern struct admin_list *admin_list;
+extern struct admin_list *admin_first;
int admin_init(void);
void admin_cleanup(void);
int admin_handle(void);
void admin_call_response(int adminid, int message, char *connected, int cause, int location, int notify);
int admin_message_to_join(struct admin_message *msg);
-int admin_message_from_join(unsigned long ref, int message_type, union parameter *param);
+int admin_message_from_join(char *remote, unsigned long ref, int message_type, union parameter *param);
diff --git a/apppbx.cpp b/apppbx.cpp
index 7dbf24e..1aeba78 100644
--- a/apppbx.cpp
+++ b/apppbx.cpp
@@ -1477,8 +1477,8 @@ int EndpointAppPBX::handler(void)
ea_endpoint->free_portlist(portlist);
}
/* put on hold */
- message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CHANNEL);
- message->param.channel = CHANNEL_STATE_HOLD;
+ message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
+ message->param.audiopath = CHANNEL_STATE_HOLD;
message_put(message);
/* indicate no patterns */
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_NOPATTERN);
@@ -1994,8 +1994,8 @@ void EndpointAppPBX::port_overlap(struct port_list *portlist, int message_type,
message_put(message);
/* connect audio, if not already */
- message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CHANNEL);
- message->param.channel = CHANNEL_STATE_CONNECT;
+ message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
+ message->param.audiopath = CHANNEL_STATE_CONNECT;
message_put(message);
} else
{
@@ -2004,8 +2004,8 @@ void EndpointAppPBX::port_overlap(struct port_list *portlist, int message_type,
message_put(message);
/* disconnect audio, if not already */
- message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CHANNEL);
- message->param.channel = CHANNEL_STATE_HOLD;
+ message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
+ message->param.audiopath = CHANNEL_STATE_HOLD;
message_put(message);
}
new_state(EPOINT_STATE_OUT_OVERLAP);
@@ -2037,8 +2037,8 @@ void EndpointAppPBX::port_proceeding(struct port_list *portlist, int message_typ
message_put(message);
/* connect audio, if not already */
- message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CHANNEL);
- message->param.channel = CHANNEL_STATE_CONNECT;
+ message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
+ message->param.audiopath = CHANNEL_STATE_CONNECT;
message_put(message);
} else
{
@@ -2047,8 +2047,8 @@ void EndpointAppPBX::port_proceeding(struct port_list *portlist, int message_typ
message_put(message);
/* disconnect audio, if not already */
- message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CHANNEL);
- message->param.channel = CHANNEL_STATE_HOLD;
+ message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
+ message->param.audiopath = CHANNEL_STATE_HOLD;
message_put(message);
}
/* if we are in a call */
@@ -2079,8 +2079,8 @@ void EndpointAppPBX::port_alerting(struct port_list *portlist, int message_type,
message_put(message);
/* connect audio, if not already */
- message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CHANNEL);
- message->param.channel = CHANNEL_STATE_CONNECT;
+ message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
+ message->param.audiopath = CHANNEL_STATE_CONNECT;
message_put(message);
} else
{
@@ -2089,8 +2089,8 @@ void EndpointAppPBX::port_alerting(struct port_list *portlist, int message_type,
message_put(message);
/* disconnect audio, if not already */
- message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CHANNEL);
- message->param.channel = CHANNEL_STATE_HOLD;
+ message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
+ message->param.audiopath = CHANNEL_STATE_HOLD;
message_put(message);
}
/* if we are in a call */
@@ -2213,8 +2213,8 @@ void EndpointAppPBX::port_connect(struct port_list *portlist, int message_type,
}
if (ea_endpoint->ep_join_id)
{
- message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CHANNEL);
- message->param.channel = CHANNEL_STATE_CONNECT;
+ message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
+ message->param.audiopath = CHANNEL_STATE_CONNECT;
message_put(message);
} else if (!e_adminid)
{
@@ -2406,8 +2406,8 @@ void EndpointAppPBX::port_disconnect_release(struct port_list *portlist, int mes
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_PATTERN);
message_put(message);
/* connect audio, if not already */
- message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CHANNEL);
- message->param.channel = CHANNEL_STATE_CONNECT;
+ message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
+ message->param.audiopath = CHANNEL_STATE_CONNECT;
message_put(message);
/* send disconnect */
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, message_type);
@@ -2540,8 +2540,8 @@ void EndpointAppPBX::port_notify(struct port_list *portlist, int message_type, u
/* tell call about it */
if (ea_endpoint->ep_join_id)
{
- message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CHANNEL);
- message->param.channel = CHANNEL_STATE_HOLD;
+ message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
+ message->param.audiopath = CHANNEL_STATE_HOLD;
message_put(message);
}
break;
@@ -2565,8 +2565,8 @@ void EndpointAppPBX::port_notify(struct port_list *portlist, int message_type, u
/* tell call about it */
if (ea_endpoint->ep_join_id)
{
- message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CHANNEL);
- message->param.channel = CHANNEL_STATE_CONNECT;
+ message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
+ message->param.audiopath = CHANNEL_STATE_CONNECT;
message_put(message);
}
break;
@@ -2971,8 +2971,8 @@ void EndpointAppPBX::join_overlap(struct port_list *portlist, int message_type,
if (e_join_pattern && e_ext.own_setup)
{
/* disconnect audio */
- message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CHANNEL);
- message->param.channel = CHANNEL_STATE_HOLD;
+ message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
+ message->param.audiopath = CHANNEL_STATE_HOLD;
message_put(message);
}
if (e_action) if (e_action->index == ACTION_OUTDIAL || e_action->index == ACTION_EXTERNAL)
@@ -2997,11 +2997,11 @@ void EndpointAppPBX::join_proceeding(struct port_list *portlist, int message_typ
if (e_join_pattern)
{
/* connect / disconnect audio */
- message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CHANNEL);
+ message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
if (e_ext.own_proceeding)
- message->param.channel = CHANNEL_STATE_HOLD;
+ message->param.audiopath = CHANNEL_STATE_HOLD;
else
- message->param.channel = CHANNEL_STATE_CONNECT;
+ message->param.audiopath = CHANNEL_STATE_CONNECT;
message_put(message);
}
// UCPY(e_join_tone, "proceeding");
@@ -3025,11 +3025,11 @@ void EndpointAppPBX::join_alerting(struct port_list *portlist, int message_type,
if (e_join_pattern)
{
/* connect / disconnect audio */
- message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CHANNEL);
+ message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
if (e_ext.own_alerting)
- message->param.channel = CHANNEL_STATE_HOLD;
+ message->param.audiopath = CHANNEL_STATE_HOLD;
else
- message->param.channel = CHANNEL_STATE_CONNECT;
+ message->param.audiopath = CHANNEL_STATE_CONNECT;
message_put(message);
}
if (portlist)
@@ -3109,8 +3109,8 @@ void EndpointAppPBX::join_connect(struct port_list *portlist, int message_type,
}
set_tone(portlist, NULL);
e_join_pattern = 0;
- message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CHANNEL);
- message->param.channel = CHANNEL_STATE_CONNECT;
+ message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
+ message->param.audiopath = CHANNEL_STATE_CONNECT;
message_put(message);
e_start = now;
}
@@ -3213,8 +3213,8 @@ void EndpointAppPBX::join_disconnect_release(struct port_list *portlist, int mes
e_join_pattern = 0;
} else /* else we enable audio */
{
- message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CHANNEL);
- message->param.channel = CHANNEL_STATE_CONNECT;
+ message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
+ message->param.audiopath = CHANNEL_STATE_CONNECT;
message_put(message);
}
/* send disconnect message */
@@ -3254,8 +3254,8 @@ void EndpointAppPBX::join_setup(struct port_list *portlist, int message_type, un
}
/* disconnect audio */
- message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CHANNEL);
- message->param.channel = CHANNEL_STATE_HOLD;
+ message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
+ message->param.audiopath = CHANNEL_STATE_HOLD;
message_put(message);
/* get dialing info */
@@ -3564,12 +3564,12 @@ void EndpointAppPBX::ea_message_join(unsigned long join_id, int message_type, un
portlist = portlist->next;
}
/* connect our audio tx and rx (blueboxing should be possibe before connect :)*/
- message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CHANNEL);
- message->param.channel = CHANNEL_STATE_CONNECT;
+ message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
+ message->param.audiopath = CHANNEL_STATE_CONNECT;
message_put(message);
// /* tell remote epoint to connect audio also, because we like to hear the patterns */
// message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_REMOTE_AUDIO);
-// message->param.channel = CHANNEL_STATE_CONNECT;
+// message->param.audiopath = CHANNEL_STATE_CONNECT;
// message_put(message);
// patterns are available, remote already connected audio
}
@@ -3583,8 +3583,8 @@ void EndpointAppPBX::ea_message_join(unsigned long join_id, int message_type, un
PDEBUG(DEBUG_EPOINT, "-> pattern becomes unavailable\n");
e_join_pattern = 0;
/* disconnect our audio tx and rx */
- message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CHANNEL);
- message->param.channel = CHANNEL_STATE_HOLD;
+ message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
+ message->param.audiopath = CHANNEL_STATE_HOLD;
message_put(message);
}
break;
@@ -3593,8 +3593,8 @@ void EndpointAppPBX::ea_message_join(unsigned long join_id, int message_type, un
/* CALL (dunno at the moment) */
case MESSAGE_REMOTE_AUDIO:
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received audio remote request.\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
- message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CHANNEL);
- message->param.channel = param->channel;
+ message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
+ message->param.audiopath = param->channel;
message_put(message);
break;
#endif
@@ -3725,13 +3725,13 @@ reject:
PERROR("EPOINT(%d) ringing endpoint's join not found.\n", ea_endpoint->ep_serial);
goto reject;
}
- if (joinpbx->c_type != JOIN_TYPE_PBX)
+ if (joinpbx->j_type != JOIN_TYPE_PBX)
{
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) ringing endpoint's join is not a PBX join, so we must reject.\n", ea_endpoint->ep_serial);
goto reject;
}
joinpbx = (class JoinPBX *)join;
- relation = joinpbx->c_relation;
+ relation = joinpbx->j_relation;
if (!relation)
{
PERROR("EPOINT(%d) ringing endpoint's join has no relation. SOFTWARE ERROR.\n", ea_endpoint->ep_serial);
@@ -3760,7 +3760,7 @@ reject:
PDEBUG(DEBUG_EPOINT, "showing all joins:\n");
while(debug_c)
{
- PDEBUG(DEBUG_EPOINT, "join=%ld\n", debug_c->c_serial);
+ PDEBUG(DEBUG_EPOINT, "join=%ld\n", debug_c->j_serial);
debug_c = debug_c->next;
}
PDEBUG(DEBUG_EPOINT, "showing all endpoints:\n");
@@ -3816,12 +3816,12 @@ reject:
message_put(message);
/* we send a connect to the audio path (not for vbox) */
- message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_CHANNEL);
- message->param.channel = CHANNEL_STATE_CONNECT;
+ message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
+ message->param.audiopath = CHANNEL_STATE_CONNECT;
message_put(message);
/* beeing paranoid, we make call update */
- joinpbx->c_updatebridge = 1;
+ joinpbx->j_updatebridge = 1;
if (options.deb & DEBUG_EPOINT)
{
@@ -3834,7 +3834,7 @@ reject:
PDEBUG(DEBUG_EPOINT, "showing all joins:\n");
while(debug_c)
{
- PDEBUG(DEBUG_EPOINT, "join=%ld\n", debug_c->c_serial);
+ PDEBUG(DEBUG_EPOINT, "join=%ld\n", debug_c->j_serial);
debug_c = debug_c->next;
}
PDEBUG(DEBUG_EPOINT, "showing all endpoints:\n");
@@ -3873,7 +3873,7 @@ void EndpointAppPBX::join_join(void)
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: our join doesn't exist anymore.\n", ea_endpoint->ep_serial);
return;
}
- if (our_join->c_type != JOIN_TYPE_PBX)
+ if (our_join->j_type != JOIN_TYPE_PBX)
{
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: join is not a pbx join.\n", ea_endpoint->ep_serial);
return;
@@ -3958,21 +3958,21 @@ void EndpointAppPBX::join_join(void)
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: other join doesn't exist anymore.\n", ea_endpoint->ep_serial);
return;
}
- if (other_join->c_type != JOIN_TYPE_PBX)
+ if (other_join->j_type != JOIN_TYPE_PBX)
{
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: other join is not a pbx join.\n", ea_endpoint->ep_serial);
return;
}
other_joinpbx = (class JoinPBX *)other_join;
- if (our_joinpbx->c_partyline && other_joinpbx->c_partyline)
+ if (our_joinpbx->j_partyline && other_joinpbx->j_partyline)
{
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: both joins are partylines.\n", ea_endpoint->ep_serial);
return;
}
/* remove relation to endpoint for join on hold */
- other_relation = other_joinpbx->c_relation;
- other_relation_pointer = &other_joinpbx->c_relation;
+ other_relation = other_joinpbx->j_relation;
+ other_relation_pointer = &other_joinpbx->j_relation;
while(other_relation)
{
if (other_relation->epoint_id == other_eapp->ea_endpoint->ep_serial)
@@ -3990,8 +3990,8 @@ void EndpointAppPBX::join_join(void)
temp_epoint = find_epoint_id(other_relation->epoint_id);
if (temp_epoint)
{
- if (temp_epoint->ep_join_id == other_join->c_serial)
- temp_epoint->ep_join_id = our_join->c_serial;
+ if (temp_epoint->ep_join_id == other_join->j_serial)
+ temp_epoint->ep_join_id = our_join->j_serial;
}
other_relation_pointer = &other_relation->next;
@@ -4000,32 +4000,32 @@ void EndpointAppPBX::join_join(void)
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) endpoint on hold removed, other enpoints on join relinked (to our join).\n", ea_endpoint->ep_serial);
/* join call relations */
- our_relation = our_joinpbx->c_relation;
- our_relation_pointer = &our_joinpbx->c_relation;
+ our_relation = our_joinpbx->j_relation;
+ our_relation_pointer = &our_joinpbx->j_relation;
while(our_relation)
{
our_relation_pointer = &our_relation->next;
our_relation = our_relation->next;
}
- *our_relation_pointer = other_joinpbx->c_relation;
- other_joinpbx->c_relation = NULL;
+ *our_relation_pointer = other_joinpbx->j_relation;
+ other_joinpbx->j_relation = NULL;
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) relations joined.\n", ea_endpoint->ep_serial);
/* release endpoint on hold */
- message = message_create(other_joinpbx->c_serial, other_eapp->ea_endpoint->ep_serial, JOIN_TO_EPOINT, MESSAGE_RELEASE);
+ message = message_create(other_joinpbx->j_serial, other_eapp->ea_endpoint->ep_serial, JOIN_TO_EPOINT, MESSAGE_RELEASE);
message->param.disconnectinfo.cause = CAUSE_NORMAL; /* normal */
message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
message_put(message);
/* if we are not a partyline, we get partyline state from other join */
- our_joinpbx->c_partyline += other_joinpbx->c_partyline;
+ our_joinpbx->j_partyline += other_joinpbx->j_partyline;
/* remove empty join */
delete other_join;
PDEBUG(DEBUG_EPOINT, "EPOINT(%d)d-join completely removed!\n");
/* mixer must update */
- our_joinpbx->c_updatebridge = 1; /* update mixer flag */
+ our_joinpbx->j_updatebridge = 1; /* update mixer flag */
/* we send a retrieve to that endpoint */
// mixer will update the hold-state of the join and send it to the endpoints is changes
@@ -4064,14 +4064,14 @@ int EndpointAppPBX::check_external(char **errstr, class Port **port)
*errstr = "No Call";
return(1);
}
- if (join->c_type != JOIN_TYPE_PBX)
+ if (join->j_type != JOIN_TYPE_PBX)
{
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) join is not a pbx join.\n", ea_endpoint->ep_serial);
*errstr = "No PBX Call";
return(1);
}
joinpbx = (class JoinPBX *)join;
- relation = joinpbx->c_relation;
+ relation = joinpbx->j_relation;
if (!relation)
{
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) join has no relation.\n", ea_endpoint->ep_serial);
diff --git a/apppbx.h b/apppbx.h
index c93f38c..43404f9 100644
--- a/apppbx.h
+++ b/apppbx.h
@@ -249,13 +249,13 @@ class EndpointAppPBX : public EndpointApp
struct route_param *routeparam(struct route_action *action, unsigned long long id);
/* init / dialing / hangup */
- void _action_init_call(int chan);
+ void _action_init_call(char *remote);
void action_init_call(void);
- void action_init_chan(void);
+ void action_init_remote(void);
void action_dialing_internal(void);
void action_dialing_external(void);
void action_dialing_h323(void);
- void action_dialing_chan(void);
+ void action_dialing_remote(void);
void action_dialing_vbox_record(void);
void action_init_partyline(void);
void action_hangup_call(void);
diff --git a/asterisk_client.c b/asterisk_client.c
index def6545..13ab261 100644
--- a/asterisk_client.c
+++ b/asterisk_client.c
@@ -9,6 +9,25 @@
** **
\*****************************************************************************/
+/*
+
+How does it work:
+
+To connect, open a socket and send a MESSAGE_HELLO to admin socket with
+the application name. This name is unique an can be used for routing calls.
+
+To make a call, send a MESSAGE_NEWREF and a new reference is received.
+When receiving a call, a new reference is received.
+The reference is received with MESSAGE_NEWREF.
+
+Make a MESSAGE_SETUP or receive a MESSAGE_SETUP with the reference.
+
+To release call and reference, send or receive MESSAGE_RELEASE.
+From that point on, the ref is not valid, so no other message may be sent
+with that reference.
+
+*/
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -138,7 +157,7 @@ int main(int argc, char *argv[])
struct sockaddr_un sock_address;
int ret;
unsigned long on = 1;
- union parameter hello_param;
+ union parameter param;
/* open socket */
if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
@@ -169,8 +188,9 @@ int main(int argc, char *argv[])
}
/* enque hello message */
- memset(&hello_param, 0, sizeof(hello_param));
- admin_asterisk(MESSAGE_HELLO, &hello_param);
+ memset(&param, 0, sizeof(param));
+ SCPY(param.hello.application, "asterisk");
+ admin_asterisk(MESSAGE_HELLO, &param);
while(42)
{
diff --git a/channel.c b/channel.c
new file mode 100644
index 0000000..56d9e0d
--- /dev/null
+++ b/channel.c
@@ -0,0 +1,257 @@
+/*****************************************************************************\
+** **
+** Linux Call Router **
+** **
+**---------------------------------------------------------------------------**
+** Copyright: Andreas Eversberg **
+** **
+** mISDN bchannel access (for Asterisk) **
+** **
+\*****************************************************************************/
+
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "main.h"
+#include <unistd.h>
+#include <poll.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+extern "C" {
+#include <net_l2.h>
+}
+
+#if 0
+#ifndef ISDN_PID_L2_B_USER
+#define ISDN_PID_L2_B_USER 0x420000ff
+#endif
+#ifndef ISDN_PID_L3_B_USER
+#define ISDN_PID_L3_B_USER 0x430000ff
+#endif
+#endif
+#ifndef ISDN_PID_L4_B_USER
+#define ISDN_PID_L4_B_USER 0x440000ff
+#endif
+
+/* used for udevice */
+int entity = 0;
+
+/* the device handler and port list */
+int mISDNdevice = -1;
+
+
+/* open mISDN device */
+void mISDNdevice_open(void)
+{
+ /* open mISDNdevice if not already open */
+ if (mISDNdevice < 0)
+ {
+ ret = mISDN_open();
+ if (ret < 0)
+ {
+ PERROR("cannot open mISDN device ret=%d errno=%d (%s) Check for mISDN modules!\nAlso did you create \"/dev/mISDN\"? Do: \"mknod /dev/mISDN c 46 0\"\n", ret, errno, strerror(errno));
+ return(NULL);
+ }
+ mISDNdevice = ret;
+ PDEBUG(DEBUG_ISDN, "mISDN device opened.\n");
+ }
+}
+
+/* close mISDN device */
+void mISDNdevice_close(void)
+{
+ if (mISDNdevice > -1)
+ {
+ mISDN_close();
+ PDEBUG(DEBUG_ISDN, "mISDN device closed.\n");
+ }
+}
+
+/* create bchannel layer */
+unsigned long mISDN_createlayer(unsigned long stid)
+{
+ unsigned long addr;
+
+ /* create new layer */
+ PDEBUG(DEBUG_BCHANNEL, "creating new layer for bchannel stid=0%x.\n" , stid);
+ memset(&li, 0, sizeof(li));
+ memset(&pid, 0, sizeof(pid));
+ li.object_id = -1;
+ li.extentions = 0;
+ li.st = stid;
+ UCPY(li.name, "B L4");
+ li.pid.layermask = ISDN_LAYER((4));
+ li.pid.protocol[4] = ISDN_PID_L4_B_USER;
+ ret = mISDN_new_layer(mISDNdevice, &li);
+ if (ret)
+ {
+ failed_new_layer:
+ PERROR("mISDN_new_layer() failed to add bchannel stid=0%x.\n", stid);
+ goto failed;
+ }
+ addr = li.id;
+ if (!li.id)
+ {
+ goto failed_new_layer;
+ }
+ PDEBUG(DEBUG_BCHANNEL, "new layer (addr=0x%x)\n", addr);
+
+ /* create new stack */
+ pid.protocol[1] = ISDN_PID_L1_B_64TRANS;
+ pid.protocol[2] = ISDN_PID_L2_B_TRANS;
+ pid.protocol[3] = ISDN_PID_L3_B_DSP;
+ pid.protocol[4] = ISDN_PID_L4_B_USER;
+ pid.layermask = ISDN_LAYER((1)) | ISDN_LAYER((2)) | ISDN_LAYER((3)) | ISDN_LAYER((4));
+ ret = mISDN_set_stack(mISDNdevice, stid, &pid);
+ if (ret)
+ {
+ stack_error:
+ PERROR("mISDN_set_stack() failed (ret=%d) to add bchannel stid=0x%x\n", ret, stid);
+ mISDN_write_frame(mISDNdevice, buff, addr, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
+ goto failed;
+ }
+ ret = mISDN_get_setstack_ind(mISDNdevice, addr);
+ if (ret)
+ goto stack_error;
+
+ /* get layer id */
+ addr = mISDN_get_layerid(mISDNdevice, stid, 4);
+ if (!addr)
+ goto stack_error;
+}
+
+/* destroy bchannel layer */
+void mISDN_destroylayer(unsigned long stid, unsigned long addr)
+{
+ /* remove our stack only if set */
+ if (addr)
+ {
+ PDEBUG(DEBUG_BCHANNEL, "free stack (addr=0x%x)\n", addr);
+ mISDN_clear_stack(mISDNdevice, stid);
+ mISDN_write_frame(mISDNdevice, buff, addr | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
+ }
+}
+
+/* do activation and deactivation of bchannel */
+static void mISDN_bchannelactivate(unsigned long addr, int activate)
+{
+ iframe_t act;
+
+ /* activate bchannel */
+ act.prim = (activate?DL_ESTABLISH:DL_RELEASE) | REQUEST;
+ act.addr = addr | FLG_MSG_DOWN;
+ act.dinfo = 0;
+ act.len = 0;
+ mISDN_write(mISDNdevice, &act, mISDN_HEADER_LEN+act.len, TIMEOUT_1SEC);
+}
+
+/* handle all mISDN messages */
+int mISDN_handler(void)
+{
+ int ret;
+ msg_t *msg;
+ iframe_t *frm;
+ struct mISDNport *mISDNport;
+ class PmISDN *isdnport;
+ net_stack_t *nst;
+ msg_t *dmsg;
+ mISDNuser_head_t *hh;
+ int i;
+
+ /* no device, no read */
+ if (mISDNdevice < 0)
+ return(0);
+
+ /* get message from kernel */
+ if (!(msg = alloc_msg(MAX_MSG_SIZE)))
+ return(1);
+ ret = mISDN_read(mISDNdevice, msg->data, MAX_MSG_SIZE, 0);
+ if (ret < 0)
+ {
+ free_msg(msg);
+ if (errno == EAGAIN)
+ return(0);
+ FATAL("Failed to do mISDN_read()\n");
+ }
+ if (!ret)
+ {
+ free_msg(msg);
+// printf("%s: ERROR: mISDN_read() returns nothing\n");
+ return(0);
+ }
+ msg->len = ret;
+ frm = (iframe_t *)msg->data;
+
+ /* global prim */
+ switch(frm->prim)
+ {
+ case MGR_DELLAYER | CONFIRM:
+ case MGR_INITTIMER | CONFIRM:
+ case MGR_ADDTIMER | CONFIRM:
+ case MGR_DELTIMER | CONFIRM:
+ case MGR_REMOVETIMER | CONFIRM:
+ free_msg(msg);
+ return(1);
+ }
+
+ /* look for channel instance, that has the address of this message */
+ chan = chan_first;
+ while(chan)
+ {
+ if (frm->addr == chan->b_addr)
+ break;
+ chan = chan->next;
+ }
+ if (!chan)
+ {
+ PERROR("message belongs to no chan: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
+ goto out;
+ }
+
+ /* b-message */
+ switch(frm->prim)
+ {
+ /* we don't care about confirms, we use rx data to sync tx */
+ case PH_DATA | CONFIRM:
+ case DL_DATA | CONFIRM:
+ break;
+
+ /* we receive audio data, we respond to it AND we send tones */
+ case PH_DATA | INDICATION:
+ case DL_DATA | INDICATION:
+ case PH_CONTROL | INDICATION:
+ i = 0;
+ chan->bchannel_receive(frm);
+ break;
+
+ case PH_ACTIVATE | INDICATION:
+ case DL_ESTABLISH | INDICATION:
+ case PH_ACTIVATE | CONFIRM:
+ case DL_ESTABLISH | CONFIRM:
+ PDEBUG(DEBUG_BCHANNEL, "DL_ESTABLISH confirm: bchannel is now activated (address 0x%x).\n", frm->addr);
+ chan->b_active = 1;
+ bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
+ break;
+
+ case PH_DEACTIVATE | INDICATION:
+ case DL_RELEASE | INDICATION:
+ case PH_DEACTIVATE | CONFIRM:
+ case DL_RELEASE | CONFIRM:
+ PDEBUG(DEBUG_BCHANNEL, "DL_RELEASE confirm: bchannel is now de-activated (address 0x%x).\n", frm->addr);
+ chan->b_active = 0;
+ bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
+ break;
+
+ default:
+ PERROR("child message not handled: prim(0x%x) addr(0x%x) msg->len(%d)\n", frm->prim, frm->addr, msg->len);
+ }
+
+ out:
+ free_msg(msg);
+ return(1);
+}
+
diff --git a/default/interface.conf b/default/interface.conf
index 6df206c..07bc818 100644
--- a/default/interface.conf
+++ b/default/interface.conf
@@ -57,8 +57,8 @@
# Also this interface will connect bchannel during call setup, so tones are
# required.
#[Ext]
-#screen_out unknown 300 national 21250993300
-#screen_out unknown 2* national 212509932*
+#screen-out unknown 300 national 21250993300
+#screen-out unknown 2* national 212509932*
#tones yes
#port 1
@@ -67,11 +67,23 @@
# 10 channels (channel 1-10) are incomming only.
# 10 channels (channel 11-15,17-21) are outgoing only.
# 10 channels (channel 22-31) are both way.
-# We prefer to use directed channels first, then we request any channel:
+# We prefer to use directed channels first, then we request any channel.
+# Outgoing calls on both-way-channels shall be indicated as "any channel".
+# (Siemens EWSD will select bot-way-channels when indicated that way.)
#[Ext]
#port 1
-#channel force,11,12,13,14,15,17,18,19,20,21,any
+#channel-in 1,2,3,4,5,6,7,8,9,10,22,23,24,25,26,27,28,29,30,31
+#channel-out force,11,12,13,14,15,17,18,19,20,21,any
+
+# Example of an ISDN interface that runs in NT-mode, but provides tones during
+# setup. Also we provide tones during setup also.
+# This is usefull to interconnect to another PBX.
+#[PBX]
+#port 5
+#earlyb yes
+#tones yes
+# Hint: Enter "lcr interface" for quick help on interface options.
# Add your interfaces here:
diff --git a/default/routing.conf b/default/routing.conf
index 0e2aaac..38e739a 100644
--- a/default/routing.conf
+++ b/default/routing.conf
@@ -5,6 +5,7 @@
# Calls with different origins will be processed in different rulesets.
[main]
+#interface=xyz : goto ruleset=xyz
extern : goto ruleset=extern
intern : goto ruleset=intern
: disconnect cause=31
@@ -13,6 +14,7 @@ intern : goto ruleset=intern
# All calls from external lines are processed here.
[extern]
+dialing=1234 remote=asterisk : remote application=asterisk
dialing=0,1234 : intern extension=200
dialing=200-299 : intern
dialing=81 : partyline room=42
diff --git a/dss1.cpp b/dss1.cpp
index 8f23c74..6aff417 100644
--- a/dss1.cpp
+++ b/dss1.cpp
@@ -812,7 +812,7 @@ void Pdss1::setup_acknowledge_ind(unsigned long prim, unsigned long dinfo, void
end_trace();
/* process channel */
- ret = received_first_reply_to_setup(prim, exclusive, channel);
+ ret = received_first_reply_to_setup(prim, channel, exclusive);
if (ret < 0)
{
message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
@@ -849,7 +849,7 @@ void Pdss1::proceeding_ind(unsigned long prim, unsigned long dinfo, void *data)
dec_ie_redir_dn(proceeding->REDIR_DN, (Q931_info_t *)((unsigned long)data+headerlen), &type, &plan, &present, (unsigned char *)redir, sizeof(redir));
end_trace();
- ret = received_first_reply_to_setup(prim, exclusive, channel);
+ ret = received_first_reply_to_setup(prim, channel, exclusive);
if (ret < 0)
{
message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
@@ -933,7 +933,7 @@ void Pdss1::alerting_ind(unsigned long prim, unsigned long dinfo, void *data)
end_trace();
/* process channel */
- ret = received_first_reply_to_setup(prim, exclusive, channel);
+ ret = received_first_reply_to_setup(prim, channel, exclusive);
if (ret < 0)
{
message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
@@ -1024,7 +1024,7 @@ void Pdss1::connect_ind(unsigned long prim, unsigned long dinfo, void *data)
/* select channel */
bchannel_before = p_m_b_channel;
- ret = received_first_reply_to_setup(prim, exclusive, channel);
+ ret = received_first_reply_to_setup(prim, channel, exclusive);
if (ret < 0)
{
message = message_create(p_serial, ACTIVE_EPOINT(p_epointlist), PORT_TO_EPOINT, MESSAGE_RELEASE);
diff --git a/dss1.h b/dss1.h
index 93f0865..488e56b 100644
--- a/dss1.h
+++ b/dss1.h
@@ -30,7 +30,7 @@ class Pdss1 : public PmISDN
void new_state(int state); /* set new state */
void isdn_show_send_message(unsigned long prim, msg_t *msg);
- int received_first_reply_to_setup(unsigned long prim, int exclusive, int channel);
+ int received_first_reply_to_setup(unsigned long prim, int channel, int exclusive);
int hunt_bchannel(int exclusive, int channel);
void information_ind(unsigned long prim, unsigned long dinfo, void *data);
void setup_ind(unsigned long prim, unsigned long dinfo, void *data);
diff --git a/interface.c b/interface.c
index 1a17842..fa7270d 100644
--- a/interface.c
+++ b/interface.c
@@ -668,7 +668,7 @@ struct interface_param interface_param[] = {
"This is required on PRI NT-mode ports that are point-to-point by default.\n"
"This parameter must follow a 'port' parameter."},
- {"channel_out", &inter_channel_out, "[force,][<number>][,...][,free][,any][,no]",
+ {"channel-out", &inter_channel_out, "[force,][<number>][,...][,free][,any][,no]",
"Channel selection list for all outgoing calls to the interface.\n"
"A free channels is searched in order of appearance.\n"
"This parameter must follow a 'port' parameter.\n"
@@ -678,10 +678,10 @@ struct interface_param interface_param[] = {
" any - On outgoing calls, signal 'any channel acceptable'. (see DSS1)\n"
" no - Signal 'no channel available' aka 'call waiting'. (see DSS1)"},
- {"channel_in", &inter_channel_in, "[force,][<number>][,...][,free][,any][,no]",
+ {"channel-in", &inter_channel_in, "[force,][<number>][,...][,free][,any][,no]",
"Channel selection list for all incomming calls from the interface.\n"
"A free channels is accepted if in the list.\n"
- "If no channel was requested, the first free channel found is selected.\n"
+ "If any channel was requested, the first free channel found is selected.\n"
"This parameter must follow a 'port' parameter.\n"
" <number>[,...] - List of channels to accept.\n"
" free - Accept any free channel"},
diff --git a/join.cpp b/join.cpp
index 2a1e0a7..df7bf67 100644
--- a/join.cpp
+++ b/join.cpp
@@ -38,8 +38,8 @@ class Join *find_join_id(unsigned long join_id)
while(join)
{
-//printf("comparing: '%s' with '%s'\n", name, join->c_name);
- if (join->c_serial == join_id)
+//printf("comparing: '%s' with '%s'\n", name, join->j_name);
+ if (join->j_serial == join_id)
return(join);
join = join->next;
}
@@ -55,8 +55,8 @@ Join::Join(void)
{
class Join **joinp;
- c_serial = join_serial++;
- c_type = JOIN_TYPE_NONE;
+ j_serial = join_serial++;
+ j_type = JOIN_TYPE_NONE;
/* attach to chain */
next = NULL;
diff --git a/join.h b/join.h
index 8c255cc..9ef2d1d 100644
--- a/join.h
+++ b/join.h
@@ -9,7 +9,7 @@
** **
\*****************************************************************************/
-enum { JOIN_TYPE_NONE, JOIN_TYPE_PBX, JOIN_TYPE_ASTERISK};
+enum { JOIN_TYPE_NONE, JOIN_TYPE_PBX, JOIN_TYPE_REMOTE};
/* join
*
@@ -26,8 +26,8 @@ class Join
virtual void message_epoint(unsigned long epoint_id, int message, union parameter *param);
virtual int handler(void);
- unsigned long c_type; /* join type (pbx or asterisk) */
- unsigned long c_serial; /* serial/unique number of join */
+ unsigned long j_type; /* join type (pbx or asterisk) */
+ unsigned long j_serial; /* serial/unique number of join */
};
void join_free(void);
diff --git a/joinpbx.cpp b/joinpbx.cpp
index 9f8f533..552352f 100644
--- a/joinpbx.cpp
+++ b/joinpbx.cpp
@@ -132,9 +132,9 @@ void joinpbx_debug(class JoinPBX *joinpbx, char *function)
if (!(options.deb & DEBUG_JOIN))
return;
- PDEBUG(DEBUG_JOIN, "join(%d) start (called from %s)\n", joinpbx->c_serial, function);
+ PDEBUG(DEBUG_JOIN, "join(%d) start (called from %s)\n", joinpbx->j_serial, function);
- relation = joinpbx->c_relation;
+ relation = joinpbx->j_relation;
if (!relation)
PDEBUG(DEBUG_JOIN, "join has no relations\n");
@@ -160,8 +160,8 @@ void joinpbx_debug(class JoinPBX *joinpbx, char *function)
UPRINT(strchr(buffer,0), "<port %ld doesn't exist>,", portlist->port_id);
portlist = portlist->next;
}
-// UPRINT(strchr(buffer,0), " endpoint=%d on=%s hold=%s", epoint->ep_serial, (epoint->ep_join_id==joinpbx->c_serial)?"yes":"no", (epoint->get_hold_id()==joinpbx->c_serial)?"yes":"no");
- UPRINT(strchr(buffer,0), " endpoint=%d on=%s", epoint->ep_serial, (epoint->ep_join_id==joinpbx->c_serial)?"yes":"no");
+// UPRINT(strchr(buffer,0), " endpoint=%d on=%s hold=%s", epoint->ep_serial, (epoint->ep_join_id==joinpbx->j_serial)?"yes":"no", (epoint->get_hold_id()==joinpbx->j_serial)?"yes":"no");
+ UPRINT(strchr(buffer,0), " endpoint=%d on=%s", epoint->ep_serial, (epoint->ep_join_id==joinpbx->j_serial)?"yes":"no");
switch(relation->type)
{
case RELATION_TYPE_CALLING:
@@ -247,19 +247,19 @@ JoinPBX::JoinPBX(class Endpoint *epoint) : Join()
PDEBUG(DEBUG_JOIN, "creating new join and connecting it to the endpoint.\n");
- c_type = JOIN_TYPE_PBX;
- c_caller[0] = '\0';
- c_caller_id[0] = '\0';
- c_dialed[0] = '\0';
- c_todial[0] = '\0';
- c_pid = getpid();
- c_updatebridge = 0;
- c_partyline = 0;
- c_multicause = CAUSE_NOUSER;
- c_multilocation = LOCATION_PRIVATE_LOCAL;
+ j_type = JOIN_TYPE_PBX;
+ j_caller[0] = '\0';
+ j_caller_id[0] = '\0';
+ j_dialed[0] = '\0';
+ j_todial[0] = '\0';
+ j_pid = getpid();
+ j_updatebridge = 0;
+ j_partyline = 0;
+ j_multicause = CAUSE_NOUSER;
+ j_multilocation = LOCATION_PRIVATE_LOCAL;
/* initialize a relation only to the calling interface */
- relation = c_relation = (struct join_relation *)MALLOC(sizeof(struct join_relation));
+ relation = j_relation = (struct join_relation *)MALLOC(sizeof(struct join_relation));
cmemuse++;
relation->type = RELATION_TYPE_CALLING;
relation->channel_state = CHANNEL_STATE_HOLD; /* audio is assumed on a new join */
@@ -280,7 +280,7 @@ JoinPBX::~JoinPBX()
{
struct join_relation *relation, *rtemp;
- relation = c_relation;
+ relation = j_relation;
while(relation)
{
rtemp = relation->next;
@@ -308,7 +308,7 @@ void JoinPBX::bridge(void)
int allmISDN = 1; // set until a non-mISDN relation is found
#endif
- relation = c_relation;
+ relation = j_relation;
while(relation)
{
/* count all relations */
@@ -325,7 +325,7 @@ void JoinPBX::bridge(void)
portlist = epoint->ep_portlist;
if (!portlist)
{
- PDEBUG(DEBUG_JOIN, "join%d ignoring relation without port object.\n", c_serial);
+ PDEBUG(DEBUG_JOIN, "join%d ignoring relation without port object.\n", j_serial);
//#warning testing: keep on hold until single audio stream available
relation->channel_state = CHANNEL_STATE_HOLD;
relation = relation->next;
@@ -333,7 +333,7 @@ void JoinPBX::bridge(void)
}
if (portlist->next)
{
- PDEBUG(DEBUG_JOIN, "join%d ignoring relation with ep%d due to port_list.\n", c_serial, epoint->ep_serial);
+ PDEBUG(DEBUG_JOIN, "join%d ignoring relation with ep%d due to port_list.\n", j_serial, epoint->ep_serial);
//#warning testing: keep on hold until single audio stream available
relation->channel_state = CHANNEL_STATE_HOLD;
relation = relation->next;
@@ -342,16 +342,16 @@ void JoinPBX::bridge(void)
port = find_port_id(portlist->port_id);
if (!port)
{
- PDEBUG(DEBUG_JOIN, "join%d ignoring relation without existing port object.\n", c_serial);
+ PDEBUG(DEBUG_JOIN, "join%d ignoring relation without existing port object.\n", j_serial);
relation = relation->next;
continue;
}
if ((port->p_type&PORT_CLASS_MASK)!=PORT_CLASS_mISDN)
{
- PDEBUG(DEBUG_JOIN, "join%d ignoring relation ep%d because it's port is not mISDN.\n", c_serial, epoint->ep_serial);
+ PDEBUG(DEBUG_JOIN, "join%d ignoring relation ep%d because it's port is not mISDN.\n", j_serial, epoint->ep_serial);
if (allmISDN)
{
- PDEBUG(DEBUG_JOIN, "join%d not all endpoints are mISDN.\n", c_serial);
+ PDEBUG(DEBUG_JOIN, "join%d not all endpoints are mISDN.\n", j_serial);
allmISDN = 0;
}
relation = relation->next;
@@ -361,9 +361,9 @@ void JoinPBX::bridge(void)
relation = relation->next;
}
- PDEBUG(DEBUG_JOIN, "join%d members=%d %s\n", c_serial, relations, (allmISDN)?"(all are mISDN-members)":"(not all are mISDN-members)");
+ PDEBUG(DEBUG_JOIN, "join%d members=%d %s\n", j_serial, relations, (allmISDN)?"(all are mISDN-members)":"(not all are mISDN-members)");
/* we notify all relations about rxdata. */
- relation = c_relation;
+ relation = j_relation;
while(relation)
{
/* count connected relations */
@@ -379,17 +379,17 @@ void JoinPBX::bridge(void)
&& relations>1 // no conf with one member
&& allmISDN) // no conf if any member is not mISDN
{
- message = message_create(c_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_mISDNSIGNAL);
+ message = message_create(j_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_mISDNSIGNAL);
message->param.mISDNsignal.message = mISDNSIGNAL_CONF;
- message->param.mISDNsignal.conf = c_serial<<16 | c_pid;
- PDEBUG(DEBUG_JOIN, "join%d EP%d +on+ id: 0x%08x\n", c_serial, relation->epoint_id, message->param.mISDNsignal.conf);
+ message->param.mISDNsignal.conf = j_serial<<16 | j_pid;
+ PDEBUG(DEBUG_JOIN, "join%d EP%d +on+ id: 0x%08x\n", j_serial, relation->epoint_id, message->param.mISDNsignal.conf);
message_put(message);
} else
{
- message = message_create(c_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_mISDNSIGNAL);
+ message = message_create(j_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_mISDNSIGNAL);
message->param.mISDNsignal.message = mISDNSIGNAL_CONF;
message->param.mISDNsignal.conf = 0;
- PDEBUG(DEBUG_JOIN, "join%d EP%d +off+ id: 0x%08x\n", c_serial, relation->epoint_id, message->param.mISDNsignal.conf);
+ PDEBUG(DEBUG_JOIN, "join%d EP%d +off+ id: 0x%08x\n", j_serial, relation->epoint_id, message->param.mISDNsignal.conf);
message_put(message);
}
@@ -399,47 +399,47 @@ void JoinPBX::bridge(void)
* - any without mISDN
* in this case we bridge
*/
- message = message_create(c_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_mISDNSIGNAL);
+ message = message_create(j_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_mISDNSIGNAL);
message->param.mISDNsignal.message = mISDNSIGNAL_JOINDATA;
message->param.mISDNsignal.joindata = (relations==2 && !allmISDN);
- PDEBUG(DEBUG_JOIN, "join%d EP%d set joindata=%d\n", c_serial, relation->epoint_id, message->param.mISDNsignal.joindata);
+ PDEBUG(DEBUG_JOIN, "join%d EP%d set joindata=%d\n", j_serial, relation->epoint_id, message->param.mISDNsignal.joindata);
message_put(message);
relation = relation->next;
}
/* two people just exchange their states */
- if (relations==2 && !c_partyline)
+ if (relations==2 && !j_partyline)
{
- PDEBUG(DEBUG_JOIN, "join%d 2 relations / no partyline\n", c_serial);
- relation = c_relation;
- relation->tx_state = notify_state_change(c_serial, relation->epoint_id, relation->tx_state, relation->next->rx_state);
- relation->next->tx_state = notify_state_change(c_serial, relation->next->epoint_id, relation->next->tx_state, relation->rx_state);
+ PDEBUG(DEBUG_JOIN, "join%d 2 relations / no partyline\n", j_serial);
+ relation = j_relation;
+ relation->tx_state = notify_state_change(j_serial, relation->epoint_id, relation->tx_state, relation->next->rx_state);
+ relation->next->tx_state = notify_state_change(j_serial, relation->next->epoint_id, relation->next->tx_state, relation->rx_state);
} else
/* one member in a join, so we put her on hold */
if (relations==1 || numconnect==1)
{
PDEBUG(DEBUG_JOIN, "join%d 1 member or only 1 connected, put on hold\n");
- relation = c_relation;
+ relation = j_relation;
while(relation)
{
if ((relation->channel_state == CHANNEL_STATE_CONNECT)
&& (relation->rx_state != NOTIFY_STATE_SUSPEND)
&& (relation->rx_state != NOTIFY_STATE_HOLD))
- relation->tx_state = notify_state_change(c_serial, relation->epoint_id, relation->tx_state, NOTIFY_STATE_HOLD);
+ relation->tx_state = notify_state_change(j_serial, relation->epoint_id, relation->tx_state, NOTIFY_STATE_HOLD);
relation = relation->next;
}
} else
/* if conference/partyline or (more than two members and more than one is connected), so we set conference state */
{
PDEBUG(DEBUG_JOIN, "join%d %d members, %d connected, signal conference\n", relations, numconnect);
- relation = c_relation;
+ relation = j_relation;
while(relation)
{
if ((relation->channel_state == CHANNEL_STATE_CONNECT)
&& (relation->rx_state != NOTIFY_STATE_SUSPEND)
&& (relation->rx_state != NOTIFY_STATE_HOLD))
- relation->tx_state = notify_state_change(c_serial, relation->epoint_id, relation->tx_state, NOTIFY_STATE_CONFERENCE);
+ relation->tx_state = notify_state_change(j_serial, relation->epoint_id, relation->tx_state, NOTIFY_STATE_CONFERENCE);
relation = relation->next;
}
}
@@ -453,11 +453,11 @@ void JoinPBX::bridge_data(unsigned long epoint_from, struct join_relation *relat
struct join_relation *relation_to;
/* if we are alone */
- if (!c_relation->next)
+ if (!j_relation->next)
return;
/* if we are more than two */
- if (c_relation->next->next)
+ if (j_relation->next->next)
return;
/* skip if source endpoint has NOT audio mode CONNECT */
@@ -465,7 +465,7 @@ void JoinPBX::bridge_data(unsigned long epoint_from, struct join_relation *relat
return;
/* get destination relation */
- relation_to = c_relation;
+ relation_to = j_relation;
if (relation_to == relation_from)
{
/* oops, we are the first, so destination is: */
@@ -480,7 +480,7 @@ void JoinPBX::bridge_data(unsigned long epoint_from, struct join_relation *relat
* will be delivered to the port
*/
//printf("from %d, to %d\n", relation_from->epoint_id, relation_to->epoint_id);
- message_forward(c_serial, relation_to->epoint_id, JOIN_TO_EPOINT, param);
+ message_forward(j_serial, relation_to->epoint_id, JOIN_TO_EPOINT, param);
}
/* release join from endpoint
@@ -500,13 +500,13 @@ int JoinPBX::release(struct join_relation *relation, int location, int cause)
if (relation->channel_state != CHANNEL_STATE_HOLD)
{
relation->channel_state = CHANNEL_STATE_HOLD;
- c_updatebridge = 1; /* update bridge flag */
+ j_updatebridge = 1; /* update bridge flag */
// note: if join is not released, bridge must be updated
}
/* detach given interface */
- reltemp = c_relation;
- relationpointer = &c_relation;
+ reltemp = j_relation;
+ relationpointer = &j_relation;
while(reltemp)
{
/* endpoint of function call */
@@ -523,7 +523,7 @@ int JoinPBX::release(struct join_relation *relation, int location, int cause)
relation = reltemp = NULL; // just in case of reuse fault;
/* if no more relation */
- if (!c_relation)
+ if (!j_relation)
{
PDEBUG(DEBUG_JOIN, "join is completely removed.\n");
/* there is no more endpoint related to the join */
@@ -533,15 +533,15 @@ int JoinPBX::release(struct join_relation *relation, int location, int cause)
PDEBUG(DEBUG_JOIN, "join completely removed!\n");
} else
/* if join is a party line */
- if (c_partyline)
+ if (j_partyline)
{
PDEBUG(DEBUG_JOIN, "join is a conference room, so we keep it alive until the last party left.\n");
} else
/* if only one relation left */
- if (!c_relation->next)
+ if (!j_relation->next)
{
PDEBUG(DEBUG_JOIN, "join has one relation left, so we send it a release with the given cause %d.\n", cause);
- message = message_create(c_serial, c_relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_RELEASE);
+ message = message_create(j_serial, j_relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_RELEASE);
message->param.disconnectinfo.cause = cause;
message->param.disconnectinfo.location = location;
message_put(message);
@@ -554,7 +554,7 @@ int JoinPBX::release(struct join_relation *relation, int location, int cause)
join = join_first;
while(join)
{
- if (options.deb & DEBUG_JOIN && join->c_type==JOIN_TYPE_PBX)
+ if (options.deb & DEBUG_JOIN && join->j_type==JOIN_TYPE_PBX)
joinpbx_debug((class JoinPBX *)join, "join_release{all joins left}");
join = join->next;
}
@@ -576,15 +576,15 @@ int joinpbx_countrelations(unsigned long join_id)
if (!join)
return(0);
- if (join->c_type != JOIN_TYPE_ASTERISK)
+ if (join->j_type != JOIN_TYPE_REMOTE)
return(2);
- if (join->c_type != JOIN_TYPE_PBX)
+ if (join->j_type != JOIN_TYPE_PBX)
return(0);
joinpbx = (class JoinPBX *)join;
i = 0;
- relation = joinpbx->c_relation;
+ relation = joinpbx->j_relation;
while(relation)
{
i++;
@@ -601,8 +601,8 @@ void JoinPBX::remove_relation(struct join_relation *relation)
if (!relation)
return;
- temp = c_relation;
- tempp = &c_relation;
+ temp = j_relation;
+ tempp = &j_relation;
while(temp)
{
if (temp == relation)
@@ -627,12 +627,12 @@ struct join_relation *JoinPBX::add_relation(void)
{
struct join_relation *relation;
- if (!c_relation)
+ if (!j_relation)
{
PERROR("there is no first relation to this join\n");
return(NULL);
}
- relation = c_relation;
+ relation = j_relation;
while(relation->next)
relation = relation->next;
@@ -676,7 +676,7 @@ void JoinPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
cl = join_first;
while(cl)
{
- if (cl->c_type == JOIN_TYPE_PBX)
+ if (cl->j_type == JOIN_TYPE_PBX)
joinpbx_debug((class JoinPBX *)cl, "Join::message_epoint{all joins before processing}");
cl = cl->next;
}
@@ -684,7 +684,7 @@ void JoinPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
}
/* check relation */
- relation = c_relation;
+ relation = j_relation;
while(relation)
{
if (relation->epoint_id == epoint_id)
@@ -693,19 +693,19 @@ void JoinPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
}
if (!relation)
{
- PDEBUG(DEBUG_JOIN, "no relation back to the endpoint found, ignoring (join=%d, endpoint=%d)\n", c_serial, epoint_id);
+ PDEBUG(DEBUG_JOIN, "no relation back to the endpoint found, ignoring (join=%d, endpoint=%d)\n", j_serial, epoint_id);
return;
}
switch(message_type)
{
- /* process channel message */
- case MESSAGE_CHANNEL:
- PDEBUG(DEBUG_JOIN, "join received channel message: %d.\n", param->channel);
- if (relation->channel_state != param->channel)
+ /* process audio path message */
+ case MESSAGE_AUDIOPATH:
+ PDEBUG(DEBUG_JOIN, "join received channel message: %d.\n", param->audiopath);
+ if (relation->channel_state != param->audiopath)
{
- relation->channel_state = param->channel;
- c_updatebridge = 1; /* update bridge flag */
+ relation->channel_state = param->audiopath;
+ j_updatebridge = 1; /* update bridge flag */
if (options.deb & DEBUG_JOIN)
joinpbx_debug(this, "Join::message_epoint{after setting new channel state}");
}
@@ -725,7 +725,7 @@ void JoinPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
if (new_state != relation->rx_state)
{
relation->rx_state = new_state;
- c_updatebridge = 1;
+ j_updatebridge = 1;
if (options.deb & DEBUG_JOIN)
joinpbx_debug(this, "Join::message_epoint{after setting new rx state}");
}
@@ -733,12 +733,12 @@ void JoinPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
default:
/* send notification to all other endpoints */
- reltemp = c_relation;
+ reltemp = j_relation;
while(reltemp)
{
if (reltemp->epoint_id!=epoint_id && reltemp->epoint_id)
{
- message = message_create(c_serial, reltemp->epoint_id, JOIN_TO_EPOINT, MESSAGE_NOTIFY);
+ message = message_create(j_serial, reltemp->epoint_id, JOIN_TO_EPOINT, MESSAGE_NOTIFY);
memcpy(&message->param, param, sizeof(union parameter));
message_put(message);
}
@@ -760,7 +760,7 @@ void JoinPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
relation->type = RELATION_TYPE_CONNECT;
/* release other relations in setup state */
release_again:
- relation = c_relation;
+ relation = j_relation;
while(relation)
{
if (relation->type == RELATION_TYPE_SETUP)
@@ -778,8 +778,8 @@ void JoinPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
if (relation->type == RELATION_TYPE_SETUP)
{
/* collect cause and send collected cause */
- collect_cause(&c_multicause, &c_multilocation, param->disconnectinfo.cause, param->disconnectinfo.location);
- release(relation, c_multilocation, c_multicause);
+ collect_cause(&j_multicause, &j_multilocation, param->disconnectinfo.cause, param->disconnectinfo.location);
+ release(relation, j_multilocation, j_multicause);
} else
{
/* send current cause */
@@ -792,32 +792,32 @@ void JoinPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
if (message_type == MESSAGE_SETUP) if (param->setup.partyline)
{
PDEBUG(DEBUG_JOIN, "respsone with connect in partyline mode.\n");
- c_partyline = param->setup.partyline;
- message = message_create(c_serial, epoint_id, JOIN_TO_EPOINT, MESSAGE_CONNECT);
- message->param.setup.partyline = c_partyline;
+ j_partyline = param->setup.partyline;
+ message = message_create(j_serial, epoint_id, JOIN_TO_EPOINT, MESSAGE_CONNECT);
+ message->param.setup.partyline = j_partyline;
message_put(message);
- c_updatebridge = 1; /* update bridge flag */
+ j_updatebridge = 1; /* update bridge flag */
}
- if (c_partyline)
+ if (j_partyline)
{
if (message_type == MESSAGE_DISCONNECT)
{
PDEBUG(DEBUG_JOIN, "releasing after receiving disconnect, because join in partyline mode.\n");
- message = message_create(c_serial, epoint_id, JOIN_TO_EPOINT, MESSAGE_RELEASE);
+ message = message_create(j_serial, epoint_id, JOIN_TO_EPOINT, MESSAGE_RELEASE);
message->param.disconnectinfo.cause = CAUSE_NORMAL;
message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
message_put(message);
return;
}
}
- if (c_partyline)
+ if (j_partyline)
{
PDEBUG(DEBUG_JOIN, "ignoring message, because join in partyline mode.\n");
return;
}
/* count relations */
- num=joinpbx_countrelations(c_serial);
+ num=joinpbx_countrelations(j_serial);
/* check number of relations */
if (num > 2)
@@ -827,7 +827,7 @@ void JoinPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
}
/* find interfaces not related to calling epoint */
- relation = c_relation;
+ relation = j_relation;
while(relation)
{
if (relation->epoint_id != epoint_id)
@@ -859,7 +859,7 @@ void JoinPBX::message_epoint(unsigned long epoint_id, int message_type, union pa
} else
{
PDEBUG(DEBUG_JOIN, "sending message ep%ld -> ep%ld.\n", epoint_id, relation->epoint_id);
- message = message_create(c_serial, relation->epoint_id, JOIN_TO_EPOINT, message_type);
+ message = message_create(j_serial, relation->epoint_id, JOIN_TO_EPOINT, message_type);
memcpy(&message->param, param, sizeof(union parameter));
message_put(message);
PDEBUG(DEBUG_JOIN, "message sent.\n");
@@ -881,10 +881,10 @@ int JoinPBX::handler(void)
// char *p;
/* the bridge must be updated */
- if (c_updatebridge)
+ if (j_updatebridge)
{
bridge();
- c_updatebridge = 0;
+ j_updatebridge = 0;
return(1);
}
@@ -945,17 +945,17 @@ int JoinPBX::out_setup(unsigned long epoint_id, int message_type, union paramete
relation->tx_state = NOTIFY_STATE_ACTIVE; /* new joins always assumed to be active */
relation->rx_state = NOTIFY_STATE_ACTIVE; /* new joins always assumed to be active */
/* create a new endpoint */
- epoint = new Endpoint(0, c_serial, 0);
+ epoint = new Endpoint(0, j_serial, 0);
if (!epoint)
FATAL("No memory for Endpoint instance\n");
if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint)))
FATAL("No memory for Endpoint Application instance\n");
relation->epoint_id = epoint->ep_serial;
/* send setup message to new endpoint */
-//printf("JOLLY DEBUG: %d\n",join_countrelations(c_serial));
+//printf("JOLLY DEBUG: %d\n",join_countrelations(j_serial));
//i if (options.deb & DEBUG_JOIN)
// joinpbx_debug(join, "Join::message_epoint");
- message = message_create(c_serial, relation->epoint_id, JOIN_TO_EPOINT, message_type);
+ message = message_create(j_serial, relation->epoint_id, JOIN_TO_EPOINT, message_type);
memcpy(&message->param, param, sizeof(union parameter));
if (newnumber)
SCPY(message->param.setup.dialinginfo.id, newnumber);
diff --git a/joinpbx.h b/joinpbx.h
index dfc391a..5cdfdd5 100644
--- a/joinpbx.h
+++ b/joinpbx.h
@@ -58,17 +58,17 @@ class JoinPBX : public Join
int handler(void);
int release(struct join_relation *relation, int location, int cause);
- char c_caller[32]; /* caller number */
- char c_caller_id[32]; /* caller id to signal */
- char c_dialed[1024]; /* dial string of (all) number(s) */
- char c_todial[32]; /* overlap dialing (part not signalled yet) */
- int c_multicause, c_multilocation;
+ char j_caller[32]; /* caller number */
+ char j_caller_id[32]; /* caller id to signal */
+ char j_dialed[1024]; /* dial string of (all) number(s) */
+ char j_todial[32]; /* overlap dialing (part not signalled yet) */
+ int j_multicause, j_multilocation;
- int c_pid; /* pid of join to generate bridge id */
- int c_updatebridge; /* bridge must be updated */
- struct join_relation *c_relation; /* list of endpoints that are related to the join */
+ int j_pid; /* pid of join to generate bridge id */
+ int j_updatebridge; /* bridge must be updated */
+ struct join_relation *j_relation; /* list of endpoints that are related to the join */
- int c_partyline; /* if set, join is conference room */
+ int j_partyline; /* if set, join is conference room */
void bridge(void);
void bridge_data(unsigned long epoint_from, struct join_relation *relation_from, union parameter *param);
diff --git a/joinasterisk.cpp b/joinremote.cpp
index 0ea0633..4b5e458 100644
--- a/joinasterisk.cpp
+++ b/joinremote.cpp
@@ -5,7 +5,7 @@
**---------------------------------------------------------------------------**
** Copyright: Andreas Eversberg **
** **
-** join functions for channel driver **
+** join functions for remote application **
** **
\*****************************************************************************/
@@ -28,22 +28,29 @@
* constructor for a new join
* the join will have a relation to the calling endpoint
*/
-JoinAsterisk::JoinAsterisk(unsigned long serial) : Join()
+JoinRemote::JoinRemote(unsigned long serial, char *remote) : Join()
{
PDEBUG(DEBUG_JOIN, "Constructor(new join)");
+ union parameter *param;
- c_type = JOIN_TYPE_ASTERISK;
+ SCPY(j_remote, remote);
+ j_type = JOIN_TYPE_REMOTE;
- c_epoint_id = serial;
- if (c_epoint_id)
- PDEBUG(DEBUG_JOIN, "New join connected to endpoint id %lu\n", c_epoint_id);
+ j_epoint_id = serial;
+ if (j_epoint_id)
+ PDEBUG(DEBUG_JOIN, "New remote join connected to endpoint id %lu and application %s\n", j_epoint_id, remote);
+
+ /* send new ref to remote socket */
+ memset(&param, 0, sizeof(param));
+ if (admin_message_from_join(j_remote, j_serial, MESSAGE_NEWREF, param)<0)
+ FATAL("No socket with remote application '%s' found, this shall not happen. because we already created one.\n", j_remote);
}
/*
* join descructor
*/
-JoinAsterisk::~JoinAsterisk()
+JoinRemote::~JoinRemote()
{
}
@@ -53,22 +60,22 @@ JoinAsterisk::~JoinAsterisk()
* it processes the current calling state.
* returns 0 if join nothing was done
*/
-int JoinAsterisk::handler(void)
+int JoinRemote::handler(void)
{
return(0);
}
-void JoinAsterisk::message_epoint(unsigned long epoint_id, int message_type, union parameter *param)
+void JoinRemote::message_epoint(unsigned long epoint_id, int message_type, union parameter *param)
{
/* if endpoint has just been removed, but still a message in the que */
- if (epoint_id != c_epoint_id)
+ if (epoint_id != j_epoint_id)
return;
- /* look for asterisk's interface */
- if (admin_message_from_join(epoint_id, message_type, param)<0)
+ /* look for Remote's interface */
+ if (admin_message_from_join(j_remote, j_serial, message_type, param)<0)
{
- PERROR("No socket with asterisk found, this shall not happen. Closing socket shall cause release of all asterisk joins\n");
+ PERROR("No socket with remote application '%s' found, this shall not happen. Closing socket shall cause release of all joins.\n", j_remote);
return;
}
@@ -79,22 +86,22 @@ void JoinAsterisk::message_epoint(unsigned long epoint_id, int message_type, uni
}
}
-void JoinAsterisk::message_asterisk(unsigned long ref, int message_type, union parameter *param)
+void JoinRemote::message_remote(unsigned long ref, int message_type, union parameter *param)
{
struct message *message;
/* create relation if no relation exists */
- if (!c_epoint_id)
+ if (!j_epoint_id)
{
class Endpoint *epoint;
- if (!(epoint = new Endpoint(0, c_serial, ref)))
+ if (!(epoint = new Endpoint(0, j_serial, ref)))
FATAL("No memory for Endpoint instance\n");
if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint)))
FATAL("No memory for Endpoint Application instance\n");
}
- message = message_create(c_serial, c_epoint_id, JOIN_TO_EPOINT, message_type);
+ message = message_create(j_serial, j_epoint_id, JOIN_TO_EPOINT, message_type);
memcpy(&message->param, param, sizeof(message->param));
message_put(message);
diff --git a/joinasterisk.h b/joinremote.h
index dfd0927..d9e7e2b 100644
--- a/joinasterisk.h
+++ b/joinremote.h
@@ -9,16 +9,17 @@
** **
\*****************************************************************************/
-class JoinAsterisk : public Join
+class JoinRemote : public Join
{
public:
- JoinAsterisk(unsigned long serial);
- ~JoinAsterisk();
+ JoinRemote(unsigned long serial, char *remote);
+ ~JoinRemote();
void message_epoint(unsigned long epoint_id, int message, union parameter *param);
- void message_asterisk(unsigned long ref, int message_type, union parameter *param);
+ void message_remote(unsigned long ref, int message_type, union parameter *param);
int handler(void);
- unsigned long c_epoint_id;
+ char j_remote[32];
+ unsigned long j_epoint_id;
};
diff --git a/mISDN.cpp b/mISDN.cpp
index 128faef..eab914a 100644
--- a/mISDN.cpp
+++ b/mISDN.cpp
@@ -1,6 +1,6 @@
/*****************************************************************************\
** **
-** PBX4Linux **
+** Linux Call Router **
** **
**---------------------------------------------------------------------------**
** Copyright: Andreas Eversberg **
@@ -25,9 +25,17 @@ extern "C" {
#include <net_l2.h>
}
+#if 0
+#ifndef ISDN_PID_L2_B_USER
#define ISDN_PID_L2_B_USER 0x420000ff
+#endif
+#ifndef ISDN_PID_L3_B_USER
#define ISDN_PID_L3_B_USER 0x430000ff
+#endif
+#endif
+#ifndef ISDN_PID_L4_B_USER
#define ISDN_PID_L4_B_USER 0x440000ff
+#endif
/* used for udevice */
int entity = 0;
@@ -381,15 +389,15 @@ failed:
* subfunction for bchannel_event
* activate request
*/
-static void _bchannel_activate(struct mISDNport *mISDNport, int i)
+static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
{
iframe_t act;
/* activate bchannel */
- chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL activate", DIRECTION_OUT);
+ chan_trace_header(mISDNport, mISDNport->b_port[i], activate?(char*)"BCHANNEL activate":(char*)"BCHANNEL deactivate", DIRECTION_OUT);
add_trace("channel", NULL, "%d", i+1+(i>=15));
end_trace();
- act.prim = DL_ESTABLISH | REQUEST;
+ act.prim = (activate?DL_ESTABLISH:DL_RELEASE) | REQUEST;
act.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN;
act.dinfo = 0;
act.len = 0;
@@ -441,24 +449,6 @@ static void _bchannel_configure(struct mISDNport *mISDNport, int i)
/*
* subfunction for bchannel_event
- * deactivate
- */
-static void _bchannel_deactivate(struct mISDNport *mISDNport, int i)
-{
- iframe_t dact;
-
- chan_trace_header(mISDNport, mISDNport->b_port[i], "BCHANNEL deactivate", DIRECTION_OUT);
- add_trace("channel", NULL, "%d", i+1+(i>=15));
- end_trace();
- dact.prim = DL_RELEASE | REQUEST;
- dact.addr = mISDNport->b_addr[i] | FLG_MSG_DOWN;
- dact.dinfo = 0;
- dact.len = 0;
- mISDN_write(mISDNdevice, &dact, mISDN_HEADER_LEN+dact.len, TIMEOUT_1SEC);
-}
-
-/*
- * subfunction for bchannel_event
* destroy stack
*/
static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
@@ -471,11 +461,13 @@ static void _bchannel_destroy(struct mISDNport *mISDNport, int i)
add_trace("stack", "address", "0x%08x", mISDNport->b_addr[i]);
end_trace();
/* remove our stack only if set */
- PDEBUG(DEBUG_BCHANNEL, "free stack (b_addr=0x%x)\n", mISDNport->b_addr[i]);
- mISDN_clear_stack(mISDNdevice, mISDNport->b_stid[i]);
if (mISDNport->b_addr[i])
+ {
+ PDEBUG(DEBUG_BCHANNEL, "free stack (b_addr=0x%x)\n", mISDNport->b_addr[i]);
+ mISDN_clear_stack(mISDNdevice, mISDNport->b_stid[i]);
mISDN_write_frame(mISDNdevice, buff, mISDNport->b_addr[i] | FLG_MSG_DOWN, MGR_DELLAYER | REQUEST, 0, 0, NULL, TIMEOUT_1SEC);
- mISDNport->b_addr[i] = 0;
+ mISDNport->b_addr[i] = 0;
+ }
}
@@ -547,7 +539,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
/* create stack and send activation request */
if (_bchannel_create(mISDNport, i))
{
- _bchannel_activate(mISDNport, i);
+ _bchannel_activate(mISDNport, i, 1);
state = B_STATE_ACTIVATING;
}
break;
@@ -577,7 +569,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
} else
{
/* bchannel is active, but not used anymore (or has wrong stack config), so we deactivate */
- _bchannel_deactivate(mISDNport, i);
+ _bchannel_activate(mISDNport, i, 0);
state = B_STATE_DEACTIVATING;
}
break;
@@ -602,7 +594,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
case B_STATE_ACTIVE:
/* bchannel is active, so we deactivate */
- _bchannel_deactivate(mISDNport, i);
+ _bchannel_activate(mISDNport, i, 0);
state = B_STATE_DEACTIVATING;
break;
@@ -630,7 +622,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
/* bchannel is now deactivate, but is requied by Port class, so we reactivate */
if (_bchannel_create(mISDNport, i))
{
- _bchannel_activate(mISDNport, i);
+ _bchannel_activate(mISDNport, i, 1);
state = B_STATE_ACTIVATING;
}
}
@@ -2300,7 +2292,7 @@ void mISDN_port_info(void)
if (stinf->pid.protocol[p])
{
useable = 0;
- printf(" -> Layer %d protocol 0x%08x is detected, but not allowed for NT lib.\n", p, stinf->pid.protocol[p]);
+ printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
}
p++;
}
@@ -2351,7 +2343,7 @@ void mISDN_port_info(void)
if (stinf->pid.protocol[p])
{
useable = 0;
- printf(" -> Layer %d protocol 0x%08x is detected, but not allowed for TE lib.\n", p, stinf->pid.protocol[p]);
+ printf(" -> Layer %d protocol 0x%08x is detected, port already in use by another application.\n", p, stinf->pid.protocol[p]);
}
p++;
}
@@ -2359,7 +2351,7 @@ void mISDN_port_info(void)
printf(" - %d B-channels\n", stinf->childcnt);
if (!useable)
- printf(" * Port NOT useable for PBX\n");
+ printf(" * Port NOT useable for LCR\n");
printf("--------\n");
diff --git a/main.h b/main.h
index 496f087..9fbf128 100644
--- a/main.h
+++ b/main.h
@@ -132,7 +132,7 @@ extern "C" {
#include "vbox.h"
#include "join.h"
#include "joinpbx.h"
-#include "joinasterisk.h"
+#include "joinremote.h"
#include "cause.h"
#include "alawulaw.h"
#include "tones.h"
diff --git a/message.h b/message.h
index cdc8163..ae1e8fd 100644
--- a/message.h
+++ b/message.h
@@ -274,6 +274,10 @@ struct param_crypt {
unsigned char data[512+32]; /* a block of 512 byte + some overhead */
};
+struct param_hello {
+ char application[32]; /* name of remote application */
+};
+
/* structure of message parameter */
union parameter {
struct param_tone tone; /* MESSAGE_TONE */
@@ -287,7 +291,7 @@ union parameter {
struct park_info parkinfo; /* MESSAGE_SUSPEND, MESSAGE_RESUME */
int state; /* MESSAGE_TIMEOUT */
int knock; /* MESSAGE_KNOCK 0=off !0=on */
- int channel; /* MESSAGE_CHANNEL see RELATION_CHANNEL_* (join.h) */
+ int audiopath; /* MESSAGE_audiopath see RELATION_CHANNEL_* (join.h) */
struct param_data data; /* MESSAGE_DATA */
struct param_play play; /* MESSAGE_VBOX_PLAY */
int speed; /* MESSAGE_VBOX_PLAY_SPEED */
@@ -295,6 +299,7 @@ union parameter {
struct param_mISDNsignal mISDNsignal; /* MESSAGE_mISDNSIGNAL */
struct extension ext; /* tell port about extension information */
struct param_crypt crypt; /* MESSAGE_CRYPT */
+ struct param_hello hello; /* MESSAGE_HELLO */
};
enum { /* message flow */
@@ -336,7 +341,7 @@ enum { /* messages between entities */
MESSAGE_SUSPEND, /* suspend port */
MESSAGE_RESUME, /* resume port */
- MESSAGE_CHANNEL, /* set status of audio path to endpoint (to call, audio is also set) */
+ MESSAGE_AUDIOPATH, /* set status of audio path to endpoint (to call, audio is also set) */
// MESSAGE_REMOTE_AUDIO, /* tell remote to set audio status */
MESSAGE_PATTERN, /* pattern information tones available */
MESSAGE_NOPATTERN, /* pattern information tones unavailable */
@@ -349,7 +354,9 @@ enum { /* messages between entities */
MESSAGE_VBOX_TONE, /* set answering VBOX tone */
MESSAGE_TONE_COUNTER, /* tone counter (for VBOX tone use) */
MESSAGE_TONE_EOF, /* tone is end of file */
- MESSAGE_HELLO, /* hello message for asterisk */
+ MESSAGE_BCHANNEL, /* request/assign bchannel */
+ MESSAGE_HELLO, /* hello message for remote application */
+ MESSAGE_NEWREF, /* special message to create and inform ref */
};
#define MESSAGES static const char *messages_txt[] = { \
@@ -370,7 +377,7 @@ enum { /* messages between entities */
"MESSAGE_FACILITY", \
"MESSAGE_SUSPEND", \
"MESSAGE_RESUME", \
- "MESSAGE_CHANNEL", \
+ "MESSAGE_AUDIOPATH", \
/* "MESSAGE_REMOTE_AUDIO",*/ \
"MESSAGE_PATTERN", \
"MESSAGE_NOPATTERN", \
@@ -381,7 +388,9 @@ enum { /* messages between entities */
"MESSAGE_VBOX_TONE", \
"MESSAGE_TONE_COUNTER", \
"MESSAGE_TONE_EOF", \
+ "MESSAGE_BCHANNEL", \
"MESSAGE_HELLO", \
+ "MESSAGE_NEWREF", \
};
diff --git a/route.c b/route.c
index f0c7c8a..3381251 100644
--- a/route.c
+++ b/route.c
@@ -92,10 +92,10 @@ struct cond_defs cond_defs[] = {
"busy=<extension>[,...]","Matches if any of the given extension is busy."},
{ "notbusy", MATCH_IDLE, COND_TYPE_STRING,
"notbusy=<extension>[,...]","Matches if any of the given extension is not busy."},
- { "asterisk", MATCH_ASTERISK, COND_TYPE_NULL,
- "asterisk","Matches if asterisk is not running with LCR channel driver."},
- { "notasterisk",MATCH_NOTASTERISK,COND_TYPE_NULL,
- "notasterisk","Matches if asterisk is not running with LCR channel driver."},
+ { "remote", MATCH_REMOTE, COND_TYPE_STRING,
+ "remote=<application name>","Matches if remote application is running."},
+ { "notremote", MATCH_NOTREMOTE,COND_TYPE_NULL,
+ "notremote=<application name>","Matches if remote application is not running."},
{ NULL, 0, 0, NULL}
};
@@ -229,6 +229,9 @@ struct param_defs param_defs[] = {
{ PARAM_STRIP,
"strip", PARAM_TYPE_NULL,
"strip", "Remove digits that were required to match this rule."},
+ { PARAM_APPLICATION,
+ "application",PARAM_TYPE_STRING,
+ "application", "Name of remote application to make call to."},
{ 0, NULL, 0, NULL, NULL}
};
@@ -245,10 +248,10 @@ struct action_defs action_defs[] = {
"outdial", &EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_external, &EndpointAppPBX::action_hangup_call,
PARAM_CONNECT | PARAM_PREFIX | PARAM_COMPLETE | PARAM_TYPE | PARAM_CAPA | PARAM_BMODE | PARAM_INFO1 | PARAM_HLC | PARAM_EXTHLC | PARAM_PRESENT | PARAM_INTERFACES | PARAM_CALLERID | PARAM_CALLERIDTYPE | PARAM_TIMEOUT,
"Same as 'extern'"},
- { ACTION_CHAN,
- "asterisk", &EndpointAppPBX::action_init_chan, &EndpointAppPBX::action_dialing_chan, &EndpointAppPBX::action_hangup_call,
- PARAM_CONNECT | PARAM_TIMEOUT,
- "Call is routed to Asterisk via channel driver."},
+ { ACTION_REMOTE,
+ "remote", &EndpointAppPBX::action_init_remote, &EndpointAppPBX::action_dialing_remote, &EndpointAppPBX::action_hangup_call,
+ PARAM_CONNECT | PARAM_APPLICATION | PARAM_TIMEOUT,
+ "Call is routed to Remote application, like Asterisk."},
{ ACTION_VBOX_RECORD,
"vbox-record",&EndpointAppPBX::action_init_call, &EndpointAppPBX::action_dialing_vbox_record, &EndpointAppPBX::action_hangup_call,
PARAM_CONNECT | PARAM_EXTENSION | PARAM_ANNOUNCEMENT | PARAM_TIMEOUT,
@@ -2208,18 +2211,18 @@ struct route_action *EndpointAppPBX::route(struct route_ruleset *ruleset)
istrue = 1;
break;
- case MATCH_ASTERISK:
- case MATCH_NOTASTERISK:
- admin = admin_list;
+ case MATCH_REMOTE:
+ case MATCH_NOTREMOTE:
+ admin = admin_first;
while(admin)
{
- if (admin->asterisk)
+ if (admin->remote[0] && !strcmp(cond->string_value, admin->remote))
break;
admin = admin->next;
}
- if (admin && cond->match==MATCH_ASTERISK)
+ if (admin && cond->match==MATCH_REMOTE)
istrue = 1;
- if (!admin && cond->match==MATCH_NOTASTERISK)
+ if (!admin && cond->match==MATCH_NOTREMOTE)
istrue = 1;
break;
@@ -2425,10 +2428,10 @@ struct route_action action_internal = {
0,
};
-struct route_action action_chan = {
+struct route_action action_remote = {
NULL,
NULL,
- ACTION_CHAN,
+ ACTION_REMOTE,
0,
0,
};
diff --git a/route.h b/route.h
index c83ffcc..7b5fded 100644
--- a/route.h
+++ b/route.h
@@ -72,8 +72,8 @@ enum { /* what to check during runtime */
MATCH_UP,
MATCH_BUSY,
MATCH_IDLE,
- MATCH_ASTERISK,
- MATCH_NOTASTERISK,
+ MATCH_REMOTE,
+ MATCH_NOTREMOTE,
};
enum { /* how to parse text file during startup */
@@ -134,6 +134,7 @@ enum { /* how to parse text file during startup */
#define PARAM_TIMEOUT (1LL<<40)
#define PARAM_NOPASSWORD (1LL<<41)
#define PARAM_STRIP (1LL<<42)
+#define PARAM_APPLICATION (1LL<<43)
/* action index
@@ -142,7 +143,7 @@ enum { /* how to parse text file during startup */
#define ACTION_EXTERNAL 0
#define ACTION_INTERNAL 1
#define ACTION_OUTDIAL 2
-#define ACTION_CHAN 3
+#define ACTION_REMOTE 3
#define ACTION_VBOX_RECORD 4
#define ACTION_PARTYLINE 5
#define ACTION_LOGIN 6
@@ -255,7 +256,7 @@ extern struct route_ruleset *ruleset_first;
extern struct route_ruleset *ruleset_main;
extern struct route_action action_external;
extern struct route_action action_internal;
-extern struct route_action action_chan;
+extern struct route_action action_remote;
extern struct route_action action_vbox;
extern struct route_action action_partyline;
extern struct route_action action_password;
diff --git a/todo.txt b/todo.txt
index 38bb842..e4eee99 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,3 +1,4 @@
+
make asterisk call implementation
display message during nothing/play
@@ -28,3 +29,16 @@ facility: diversion, 3pty, ...
VLAN-Kamera
+
+chan.cpp
+
+struct Channel *chan_first;
+
+chan->bchannel_receive
+
+struct ChanAsterisk *chanasterisk;
+
+
+
+
+
diff --git a/trace.c b/trace.c
index 02a39b3..f7ff74b 100644
--- a/trace.c
+++ b/trace.c
@@ -307,7 +307,7 @@ void end_trace(void)
}
/* process admin */
- admin = admin_list;
+ admin = admin_first;
while(admin)
{
if (admin->trace.detail)