summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuper User2007-08-11 15:57:58 +0200
committerSuper User2007-08-11 15:57:58 +0200
commitcbe9d412a37e75b61cc74e8a65b0293923eb5160 (patch)
tree8aaf96ba18a5cbc2f5aed9fc0f16c87d7f5559b4
parentfixes, debugging for usleep problems. (diff)
downloadlcr-cbe9d412a37e75b61cc74e8a65b0293923eb5160.tar.gz
lcr-cbe9d412a37e75b61cc74e8a65b0293923eb5160.tar.xz
lcr-cbe9d412a37e75b61cc74e8a65b0293923eb5160.zip
added exporting/importing bchannel stacks to the remote application
-rw-r--r--admin_client.c35
-rw-r--r--admin_server.c17
-rw-r--r--apppbx.cpp75
-rw-r--r--dss1.cpp20
-rw-r--r--endpoint.cpp7
-rw-r--r--endpoint.h2
-rw-r--r--joinpbx.cpp2
-rw-r--r--joinremote.cpp48
-rw-r--r--joinremote.h3
-rw-r--r--mISDN.cpp305
-rw-r--r--mISDN.h25
-rw-r--r--message.h31
-rw-r--r--message.txt31
13 files changed, 504 insertions, 97 deletions
diff --git a/admin_client.c b/admin_client.c
index 6bf964c..dac2b78 100644
--- a/admin_client.c
+++ b/admin_client.c
@@ -717,12 +717,41 @@ char *admin_state(int sock, char *argv[])
if (m[i].u.i.l2link && m[i].u.i.block==0)
{
ptmp:
- color((m[i].u.i.busy[j])?yellow:blue);
- addstr((m[i].u.i.busy[j])?"busy":"idle");
+ switch(m[i].u.i.busy[j])
+ {
+ case B_STATE_IDLE:
+ color(blue);
+ addstr("idle ");
+ break;
+ case B_STATE_ACTIVATING:
+ color(yellow);
+ addstr("act'ing ");
+ break;
+ case B_STATE_ACTIVE:
+ color(green);
+ addstr("busy ");
+ break;
+ case B_STATE_DEACTIVATING:
+ color(yellow);
+ addstr("dact'ing");
+ break;
+ case B_STATE_EXPORTING:
+ color(yellow);
+ addstr("exp'ing ");
+ break;
+ case B_STATE_REMOTE:
+ color(green);
+ addstr("remote ");
+ break;
+ case B_STATE_IMPORTING:
+ color(yellow);
+ addstr("imp'ing ");
+ break;
+ }
} else
{
color(red);
- addstr("blk ");
+ addstr("blocked ");
}
if (m[i].u.i.port[j])
{
diff --git a/admin_server.c b/admin_server.c
index f1275a6..6b0647b 100644
--- a/admin_server.c
+++ b/admin_server.c
@@ -107,7 +107,7 @@ void free_connection(struct admin_list *admin)
memset(&param, 0, sizeof(param));
param.disconnectinfo.cause = CAUSE_OUTOFORDER;
param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
- ((class JoinRemote *)join)->message_remote(0, MESSAGE_RELEASE, &param);
+ ((class JoinRemote *)join)->message_remote(MESSAGE_RELEASE, &param);
/* join is now destroyed, so we go to next join */
}
join = joinnext;
@@ -511,7 +511,7 @@ int admin_call(struct admin_list *admin, struct admin_message *msg)
class Endpoint *epoint;
class EndpointAppPBX *apppbx;
- if (!(epoint = new Endpoint(0, 0, 0)))
+ if (!(epoint = new Endpoint(0, 0)))
FATAL("No memory for Endpoint instance\n");
if (!(epoint->ep_app = apppbx = new DEFAULT_ENDPOINT_APP(epoint)))
FATAL("No memory for Endpoint Application instance\n");
@@ -641,6 +641,17 @@ int admin_message_to_join(struct admin_msg *msg, char *remote_name, int sock_id)
return(0);
}
+ /* bchannel message
+ * no ref given for *_ack */
+ if (msg->type == MESSAGE_BCHANNEL)
+ if (msg->param.bchannel.type == BCHANNEL_ASSIGN_ACK
+ || msg->param.bchannel.type == BCHANNEL_REMOVE_ACK)
+ {
+ /* no ref, but address */
+ message_bchannel_from_join(NULL, msg->param.bchannel.type, msg->param.bchannel.addr);
+ return(0);
+ }
+
/* check for ref */
if (!msg->ref)
{
@@ -675,7 +686,7 @@ int admin_message_to_join(struct admin_msg *msg, char *remote_name, int sock_id)
}
/* send message */
- ((class JoinRemote *)join)->message_remote(msg->ref, msg->type, &msg->param);
+ ((class JoinRemote *)join)->message_remote(msg->type, &msg->param);
return(0);
}
diff --git a/apppbx.cpp b/apppbx.cpp
index 1cef961..375980a 100644
--- a/apppbx.cpp
+++ b/apppbx.cpp
@@ -2901,14 +2901,15 @@ void EndpointAppPBX::ea_message_port(unsigned long port_id, int message_type, un
port_resume(portlist, message_type, param);
break;
+#if 0
/* port assigns bchannel */
- case MESSAGE_BCHANNEL: /* indicates the assigned bchannel */
- case MESSAGE_BCHANNEL_FREE: /* requests bchannel back (e.g. when call is holded) */
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received bchannel assignment.\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
+ case MESSAGE_BCHANNEL: /* bchannel assignment messafe */
+ PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received bchannel message %d from port.\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id, param->bchannel.type);
/* only one port is expected to be connected to bchannel */
message = message_forward(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, param);
logmessage(message->type, &message->param, portlist->port_id, DIRECTION_IN);
break;
+#endif
default:
@@ -3459,7 +3460,7 @@ void EndpointAppPBX::join_notify(struct port_list *portlist, int message_type, u
}
}
-/* call sends messages to the endpoint
+/* JOIN sends messages to the endpoint
*/
void EndpointAppPBX::ea_message_join(unsigned long join_id, int message_type, union parameter *param)
{
@@ -3468,7 +3469,7 @@ void EndpointAppPBX::ea_message_join(unsigned long join_id, int message_type, un
if (!join_id)
{
- PERROR("EPOINT(%d) error: call == NULL.\n", ea_endpoint->ep_serial);
+ PERROR("EPOINT(%d) error: JOIN == NULL.\n", ea_endpoint->ep_serial);
return;
}
@@ -3477,7 +3478,7 @@ void EndpointAppPBX::ea_message_join(unsigned long join_id, int message_type, un
/* send MESSAGE_DATA to port */
if (message_type == MESSAGE_DATA)
{
- if (join_id == ea_endpoint->ep_join_id) // still linked with call
+ if (join_id == ea_endpoint->ep_join_id) // still linked with JOIN
{
/* skip if no port relation */
if (!portlist)
@@ -3491,28 +3492,28 @@ void EndpointAppPBX::ea_message_join(unsigned long join_id, int message_type, un
}
}
-// PDEBUG(DEBUG_EPOINT, "EPOINT(%d) received message %d for active call (terminal %s, caller id %s state=%d)\n", ea_endpoint->ep_serial, message, e_ext.number, e_callerinfo.id, e_state);
+// PDEBUG(DEBUG_EPOINT, "EPOINT(%d) received message %d for active JOIN (terminal %s, caller id %s state=%d)\n", ea_endpoint->ep_serial, message, e_ext.number, e_callerinfo.id, e_state);
switch(message_type)
{
- /* CALL SENDS CRYPT message */
+ /* JOIN SENDS CRYPT message */
case MESSAGE_CRYPT:
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received crypt message: '%d'\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id, param->crypt.type);
join_crypt(portlist, message_type, param);
break;
- /* CALL sends INFORMATION message */
+ /* JOIN sends INFORMATION message */
case MESSAGE_INFORMATION:
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received more digits: '%s'\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id, param->information.id);
join_information(portlist, message_type, param);
break;
- /* CALL sends FACILITY message */
+ /* JOIN sends FACILITY message */
case MESSAGE_FACILITY:
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received facility\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
join_facility(portlist, message_type, param);
break;
- /* CALL sends OVERLAP message */
+ /* JOIN sends OVERLAP message */
case MESSAGE_OVERLAP:
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received 'more info available'\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
if (e_state!=EPOINT_STATE_IN_SETUP
@@ -3524,7 +3525,7 @@ void EndpointAppPBX::ea_message_join(unsigned long join_id, int message_type, un
join_overlap(portlist, message_type, param);
break;
- /* CALL sends PROCEEDING message */
+ /* JOIN sends PROCEEDING message */
case MESSAGE_PROCEEDING:
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s (caller id '%s') received proceeding\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
if(e_state!=EPOINT_STATE_IN_OVERLAP)
@@ -3535,7 +3536,7 @@ void EndpointAppPBX::ea_message_join(unsigned long join_id, int message_type, un
join_proceeding(portlist, message_type, param);
break;
- /* CALL sends ALERTING message */
+ /* JOIN sends ALERTING message */
case MESSAGE_ALERTING:
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received alerting\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
if (e_state!=EPOINT_STATE_IN_OVERLAP
@@ -3547,7 +3548,7 @@ void EndpointAppPBX::ea_message_join(unsigned long join_id, int message_type, un
join_alerting(portlist, message_type, param);
break;
- /* CALL sends CONNECT message */
+ /* JOIN sends CONNECT message */
case MESSAGE_CONNECT:
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received connect\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
if (e_state!=EPOINT_STATE_IN_OVERLAP
@@ -3560,29 +3561,29 @@ void EndpointAppPBX::ea_message_join(unsigned long join_id, int message_type, un
join_connect(portlist, message_type, param);
break;
- /* CALL sends DISCONNECT/RELEASE message */
- case MESSAGE_DISCONNECT: /* call disconnect */
- case MESSAGE_RELEASE: /* call releases */
+ /* JOIN sends DISCONNECT/RELEASE message */
+ case MESSAGE_DISCONNECT: /* JOIN disconnect */
+ case MESSAGE_RELEASE: /* JOIN releases */
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received %s with cause %d location %d\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id, (message_type==MESSAGE_DISCONNECT)?"disconnect":"release", param->disconnectinfo.cause, param->disconnectinfo.location);
join_disconnect_release(message_type, param);
break;
- /* CALL sends SETUP message */
+ /* JOIN sends SETUP message */
case MESSAGE_SETUP:
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint received setup from terminal='%s',id='%s' to id='%s' (dialing itype=%d)\n", ea_endpoint->ep_serial, param->setup.callerinfo.extension, param->setup.callerinfo.id, param->setup.dialinginfo.id, param->setup.dialinginfo.itype);
join_setup(portlist, message_type, param);
break;
- /* CALL sends special mISDNSIGNAL message */
+ /* JOIN sends special mISDNSIGNAL message */
case MESSAGE_mISDNSIGNAL: /* isdn message to port */
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received mISDNsignal message.\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
join_mISDNsignal(portlist, message_type, param);
break;
- /* call requests bchannel */
+#if 0
+ /* JOIN requests bchannel */
case MESSAGE_BCHANNEL: /* indicates the need of own bchannel access */
- case MESSAGE_BCHANNEL_FREE: /* indicates that the bchannel is free */
- PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received bchannel request.\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
+ PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received bchannel assignment %d from join.\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id, param->bchannel.type);
/* only one port is expected to be connected to bchannel */
if (!portlist)
break;
@@ -3594,8 +3595,9 @@ void EndpointAppPBX::ea_message_join(unsigned long join_id, int message_type, un
message = message_forward(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, param);
logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
break;
+#endif
- /* CALL has pattern available */
+ /* JOIN has pattern available */
case MESSAGE_PATTERN: /* indicating pattern available */
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received pattern availability.\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
if (!e_join_pattern)
@@ -3620,7 +3622,7 @@ void EndpointAppPBX::ea_message_join(unsigned long join_id, int message_type, un
}
break;
- /* CALL has no pattern available */
+ /* JOIN has no pattern available */
case MESSAGE_NOPATTERN: /* indicating no pattern available */
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received pattern NOT available.\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
if (e_join_pattern)
@@ -3635,7 +3637,7 @@ void EndpointAppPBX::ea_message_join(unsigned long join_id, int message_type, un
break;
#if 0
- /* CALL (dunno at the moment) */
+ /* JOIN (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_AUDIOPATH);
@@ -3644,7 +3646,7 @@ void EndpointAppPBX::ea_message_join(unsigned long join_id, int message_type, un
break;
#endif
- /* CALL sends a notify message */
+ /* JOIN sends a notify message */
case MESSAGE_NOTIFY:
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) epoint with terminal '%s' (caller id '%s') received notify.\n", ea_endpoint->ep_serial, e_ext.number, e_callerinfo.id);
join_notify(portlist, message_type, param);
@@ -4478,13 +4480,32 @@ void EndpointAppPBX::logmessage(int message_type, union parameter *param, unsign
end_trace();
break;
+#if 0
case MESSAGE_BCHANNEL:
- case MESSAGE_BCHANNEL_FREE:
trace_header("BCHANNEL", dir);
+ switch(param->bchannel.type)
+ {
+ case BCHANNEL_REQUEST:
+ add_trace("type", NULL, "request");
+ break;
+ case BCHANNEL_ASSIGN:
+ add_trace("type", NULL, "assign");
+ break;
+ case BCHANNEL_ASSIGN_ACK:
+ add_trace("type", NULL, "assign_ack");
+ break;
+ case BCHANNEL_REMOVE:
+ add_trace("type", NULL, "remove");
+ break;
+ case BCHANNEL_REMOVE_ACK:
+ add_trace("type", NULL, "remove_ack");
+ break;
+ }
if (param->bchannel.addr)
add_trace("address", NULL, "%x", param->bchannel.addr);
end_trace();
break;
+#endif
default:
PERROR("EPOINT(%d) message not of correct type (%d)\n", ea_endpoint->ep_serial, message_type);
diff --git a/dss1.cpp b/dss1.cpp
index a52f66e..9a6a922 100644
--- a/dss1.cpp
+++ b/dss1.cpp
@@ -164,7 +164,7 @@ int Pdss1::received_first_reply_to_setup(unsigned long prim, int channel, int ex
end_trace();
/* activate our exclusive channel */
- bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_ACTIVATE);
+ bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE, p_m_exportremote);
} else
if (p_m_b_channel)
{
@@ -185,7 +185,7 @@ int Pdss1::received_first_reply_to_setup(unsigned long prim, int channel, int ex
add_trace("connect", "channel", "%d", p_m_b_channel);
end_trace();
p_m_b_exclusive = 1; // we are done
- bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_ACTIVATE);
+ bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE, p_m_exportremote);
return(0);
}
@@ -212,7 +212,7 @@ int Pdss1::received_first_reply_to_setup(unsigned long prim, int channel, int ex
end_trace();
/* activate channel given by remote */
- bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_ACTIVATE);
+ bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE, p_m_exportremote);
} else
if (p_m_b_reserve)
{
@@ -248,7 +248,7 @@ int Pdss1::received_first_reply_to_setup(unsigned long prim, int channel, int ex
end_trace();
/* activate channel given by remote */
- bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_ACTIVATE);
+ bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE, p_m_exportremote);
} else
{
/*** we sent 'no channel available' ***/
@@ -277,7 +277,7 @@ int Pdss1::received_first_reply_to_setup(unsigned long prim, int channel, int ex
p_m_b_exclusive = 1; // we are done
/* activate channel given by remote */
- bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_ACTIVATE);
+ bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE, p_m_exportremote);
return(0);
}
@@ -312,7 +312,7 @@ int Pdss1::received_first_reply_to_setup(unsigned long prim, int channel, int ex
p_m_b_exclusive = 1; // we are done
/* activate channel given by remote */
- bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_ACTIVATE);
+ bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE, p_m_exportremote);
}
return(0);
@@ -731,12 +731,12 @@ void Pdss1::setup_ind(unsigned long prim, unsigned long dinfo, void *data)
p_m_delete = 1;
return;
}
- bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_ACTIVATE);
+ bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE, p_m_exportremote);
/* create endpoint */
if (p_epointlist)
FATAL("Incoming call but already got an endpoint.\n");
- if (!(epoint = new Endpoint(p_serial, 0, 0)))
+ if (!(epoint = new Endpoint(p_serial, 0)))
FATAL("No memory for Endpoint instance\n");
if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint)))
FATAL("No memory for Endpoint Application instance\n");
@@ -1473,7 +1473,7 @@ void Pdss1::retrieve_ind(unsigned long prim, unsigned long dinfo, void *data)
cause = -ret;
goto reject;
}
- bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_ACTIVATE);
+ bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE, p_m_exportremote);
/* set hold state */
p_m_hold = 0;
@@ -1645,7 +1645,7 @@ void Pdss1::resume_ind(unsigned long prim, unsigned long dinfo, void *data)
p_m_delete = 1;
return;
}
- bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_ACTIVATE);
+ bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_USE, p_m_exportremote);
/* create endpoint */
if (p_epointlist)
diff --git a/endpoint.cpp b/endpoint.cpp
index b5d6f64..e0f6365 100644
--- a/endpoint.cpp
+++ b/endpoint.cpp
@@ -39,7 +39,7 @@ class Endpoint *find_epoint_id(unsigned long epoint_id)
/*
* endpoint constructor (link with either port or join id)
*/
-Endpoint::Endpoint(unsigned long port_id, unsigned long join_id, unsigned long use_epoint_id)
+Endpoint::Endpoint(unsigned long port_id, unsigned long join_id)
{
class Port *port;
class Endpoint **epointpointer;
@@ -60,10 +60,7 @@ Endpoint::Endpoint(unsigned long port_id, unsigned long join_id, unsigned long u
*epointpointer = this;
/* serial */
- if (use_epoint_id)
- ep_serial = use_epoint_id;
- else
- ep_serial = epoint_serial++;
+ ep_serial = epoint_serial++;
/* link to join or port */
if (port_id)
diff --git a/endpoint.h b/endpoint.h
index 460c0d7..a336beb 100644
--- a/endpoint.h
+++ b/endpoint.h
@@ -22,7 +22,7 @@ struct port_list {
class Endpoint
{
public:
- Endpoint(unsigned long port_id, unsigned long join_id, unsigned long use_epoint_id);
+ Endpoint(unsigned long port_id, unsigned long join_id);
~Endpoint();
class Endpoint *next; /* next in list */
unsigned long ep_serial; /* a unique serial to identify */
diff --git a/joinpbx.cpp b/joinpbx.cpp
index ff8fcd1..6d8b1b9 100644
--- a/joinpbx.cpp
+++ b/joinpbx.cpp
@@ -983,7 +983,7 @@ 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, j_serial, 0);
+ epoint = new Endpoint(0, j_serial);
if (!epoint)
FATAL("No memory for Endpoint instance\n");
if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint)))
diff --git a/joinremote.cpp b/joinremote.cpp
index 3b7291c..f2c08b7 100644
--- a/joinremote.cpp
+++ b/joinremote.cpp
@@ -37,12 +37,13 @@ JoinRemote::JoinRemote(unsigned long serial, char *remote_name, int remote_id) :
j_remote_id = remote_id;
j_type = JOIN_TYPE_REMOTE;
- j_epoint_id = serial;
+ j_epoint_id = serial; /* this is the endpoint, if created by epoint */
if (j_epoint_id)
PDEBUG(DEBUG_JOIN, "New remote join connected to endpoint id %lu and application %s\n", j_epoint_id, remote_name);
/* send new ref to remote socket */
memset(&param, 0, sizeof(param));
+ /* the j_serial is assigned by Join() parent. this is sent as new ref */
if (admin_message_from_join(j_remote_id, 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_name);
}
@@ -53,7 +54,6 @@ JoinRemote::JoinRemote(unsigned long serial, char *remote_name, int remote_id) :
*/
JoinRemote::~JoinRemote()
{
-
}
@@ -87,7 +87,7 @@ void JoinRemote::message_epoint(unsigned long epoint_id, int message_type, union
}
}
-void JoinRemote::message_remote(unsigned long ref, int message_type, union parameter *param)
+void JoinRemote::message_remote(int message_type, union parameter *param)
{
struct message *message;
@@ -96,12 +96,22 @@ void JoinRemote::message_remote(unsigned long ref, int message_type, union param
{
class Endpoint *epoint;
- if (!(epoint = new Endpoint(0, j_serial, ref)))
+ if (!(epoint = new Endpoint(0, j_serial)))
FATAL("No memory for Endpoint instance\n");
+ j_epoint_id = epoint->ep_serial;
if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint)))
FATAL("No memory for Endpoint Application instance\n");
}
+ /* set serial on bchannel message
+ * also ref is given, so we send message with ref */
+ if (message_type == MESSAGE_BCHANNEL)
+ {
+ message_bchannel_from_join(this, param->bchannel.type, param->bchannel.addr);
+ return;
+ }
+
+ /* cannot just forward, because param is not of container "struct message" */
message = message_create(j_serial, j_epoint_id, JOIN_TO_EPOINT, message_type);
memcpy(&message->param, param, sizeof(message->param));
message_put(message);
@@ -113,5 +123,35 @@ void JoinRemote::message_remote(unsigned long ref, int message_type, union param
}
}
+void message_bchannel_to_join(int serial, int type, unsigned long addr)
+{
+ union parameter param;
+ class Join *join;
+ class JoinRemote *joinremote;
+
+ /* find join serial */
+ join = find_join_id(serial);
+ if (!join)
+ {
+ PDEBUG(DEBUG_JOIN | DEBUG_BCHANNEL, "Join %d not found\n", serial);
+ return;
+ }
+ if (!join->j_type != JOIN_TYPE_REMOTE)
+ {
+ PERROR("Join %d not of remote type. This shall not happen.\n", serial);
+ return;
+ }
+ joinremote = (class JoinRemote *)join;
+
+ memset(&param, 0, sizeof(union parameter));
+ param.bchannel.type = type;
+ param.bchannel.addr = addr;
+ if (admin_message_from_join(joinremote->j_remote_id, joinremote->j_serial, MESSAGE_BCHANNEL, &param)<0)
+ {
+ PERROR("No socket with remote application '%s' found, this shall not happen. Closing socket shall cause release of all joins.\n", joinremote->j_remote_name);
+ return;
+ }
+}
+
diff --git a/joinremote.h b/joinremote.h
index ac86467..f80d0d9 100644
--- a/joinremote.h
+++ b/joinremote.h
@@ -15,7 +15,7 @@ class JoinRemote : public Join
JoinRemote(unsigned long serial, char *remote_name, int remote_id);
~JoinRemote();
void message_epoint(unsigned long epoint_id, int message, union parameter *param);
- void message_remote(unsigned long ref, int message_type, union parameter *param);
+ void message_remote(int message_type, union parameter *param);
int handler(void);
int j_remote_id;
@@ -24,3 +24,4 @@ class JoinRemote : public Join
};
+void message_bchannel_to_join(int serial, int type, unsigned long addr);
diff --git a/mISDN.cpp b/mISDN.cpp
index 66c17ee..6196ee2 100644
--- a/mISDN.cpp
+++ b/mISDN.cpp
@@ -159,6 +159,7 @@ PmISDN::PmISDN(int type, mISDNport *mISDNport, char *portname, struct port_setti
p_m_dtmf = !mISDNport->ifport->nodtmf;
p_m_timeout = 0;
p_m_timer = 0;
+ p_m_exportremote = 0; /* channel shall be exported to given remote */
/* audio */
p_m_load = 0;
@@ -472,7 +473,7 @@ failed:
/*
* subfunction for bchannel_event
- * activate request
+ * activate / deactivate request
*/
static void _bchannel_activate(struct mISDNport *mISDNport, int i, int activate)
{
@@ -582,21 +583,43 @@ It may be linked to a Port class, that likes to reactivate it.
See above.
After deactivating bchannel, and if not used, the bchannel becomes idle again.
+Also the bchannel may be exported, but only if the state is or becomes idle:
+
+- B_STATE_EXPORTING
+The bchannel assignment has been sent to the remove application.
+
+- B_STATE_REMOTE
+The bchannel assignment is acknowledged by the remote application.
+
+- B_STATE_IMPORTING
+The bchannel is re-imported by mISDN port object.
+
+- B_STATE_IDLE
+See above.
+After re-importing bchannel, and if not used, the bchannel becomes idle again.
+
A bchannel can have the following events:
-- B_EVENT_ACTIVATE
+- B_EVENT_USE
A bchannel is required by a Port class.
+The bchannel shall be exported to the remote application.
- B_EVENT_ACTIVATED
The bchannel beomes active.
-- B_EVENT_DEACTIVATE
+- B_EVENT_DROP
The bchannel is not required by Port class anymore
- B_EVENT_DEACTIVATED
The bchannel becomes inactive.
+- B_EVENT_EXPORTED
+The bchannel is now used by remote application.
+
+- B_EVENT_IMPORTED
+The bchannel is not used by remote application.
+
All actions taken on these events depend on the current bchannel's state and if it is linked to a Port class.
*/
@@ -608,36 +631,106 @@ All actions taken on these events depend on the current bchannel's state and if
* - event is the B_EVENT_* value
* - port is the PmISDN class pointer
*/
-void bchannel_event(struct mISDNport *mISDNport, int i, int event)
+void bchannel_event(struct mISDNport *mISDNport, int i, int event, unsigned long to_remote)
{
+ class PmISDN *b_port = mISDNport->b_port[i];
int state = mISDNport->b_state[i];
+ unsigned long remote = mISDNport->b_remote[i];
+ unsigned long addr = mISDNport->b_addr[i];
switch(event)
{
- case B_EVENT_ACTIVATE:
+ case B_EVENT_USE:
/* port must be linked in order to allow activation */
- if (!mISDNport->b_port[i])
+ if (!b_port)
FATAL("bchannel must be linked to a Port class\n");
switch(state)
{
case B_STATE_IDLE:
- /* create stack and send activation request */
- if (_bchannel_create(mISDNport, i))
+ if (remote)
+ PDEBUG(DEBUG_BCHANNEL, "idle channels don't have remote link.\n");
+ if (to_remote)
{
- _bchannel_activate(mISDNport, i, 1);
- state = B_STATE_ACTIVATING;
+ /* export bchannel */
+ mISDNport->b_remote[i] = remote = to_remote;
+
+ message_bchannel_to_join(remote, BCHANNEL_ASSIGN, addr);
+ chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
+ add_trace("type", NULL, "assign");
+ add_trace("stack", "address", "%x", addr);
+ end_trace();
+ state = B_STATE_EXPORTING;
+ } else
+ {
+ /* create stack and send activation request */
+ if (_bchannel_create(mISDNport, i))
+ {
+ _bchannel_activate(mISDNport, i, 1);
+ state = B_STATE_ACTIVATING;
+ }
}
break;
case B_STATE_ACTIVATING:
+ case B_STATE_EXPORTING:
+ /* do nothing, because it is already activating */
+ break;
+
+ case B_STATE_DEACTIVATING:
+ case B_STATE_IMPORTING:
+ /* do nothing, because we must wait until we can reactivate */
+ break;
+
+ default:
+ /* problems that might ocurr:
+ * B_EVENT_USE is received when channel already in use.
+ * bchannel exported, but not freed by other port
+ */
+ PERROR("Illegal event %d at state %d, please correct.\n", event, state);
+ }
+ break;
+
+ case B_EVENT_EXPORTREQUEST:
+ /* special case where the bchannel is requested by remote */
+ if (remote)
+ {
+ PERROR("channel for join %d already exported to join %d, please correct.\n", to_remote, remote);
+ }
+ mISDNport->b_remote[i] = remote = to_remote;
+ switch(state)
+ {
+ case B_STATE_IDLE:
+
+ /* export bchannel */
+ message_bchannel_to_join(remote, BCHANNEL_ASSIGN, addr);
+ chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
+ add_trace("type", NULL, "assign");
+ add_trace("stack", "address", "%x", addr);
+ end_trace();
+ state = B_STATE_EXPORTING;
+ break;
+
+ case B_STATE_ACTIVATING:
+ case B_STATE_EXPORTING:
/* do nothing, because it is already activating */
break;
case B_STATE_DEACTIVATING:
+ case B_STATE_IMPORTING:
/* do nothing, because we must wait until we can reactivate */
break;
+ case B_STATE_ACTIVE:
+ /* bchannel is active, so we deactivate */
+ _bchannel_activate(mISDNport, i, 0);
+ state = B_STATE_DEACTIVATING;
+ break;
+
default:
+ /* problems that might ocurr:
+ * ... when channel already in use.
+ * bchannel exported, but not freed by other port
+ */
PERROR("Illegal event %d at state %d, please correct.\n", event, state);
}
break;
@@ -646,14 +739,14 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
switch(state)
{
case B_STATE_ACTIVATING:
- if (mISDNport->b_port[i])
+ if (b_port && !remote)
{
/* bchannel is active and used by Port class, so we configure bchannel */
_bchannel_configure(mISDNport, i);
state = B_STATE_ACTIVE;
} else
{
- /* bchannel is active, but not used anymore (or has wrong stack config), so we deactivate */
+ /* bchannel is active, but exported OR not used anymore (or has wrong stack config), so we deactivate */
_bchannel_activate(mISDNport, i, 0);
state = B_STATE_DEACTIVATING;
}
@@ -664,9 +757,35 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
}
break;
- case B_EVENT_DEACTIVATE:
- if (!mISDNport->b_port[i])
+ case B_EVENT_EXPORTED:
+ switch(state)
+ {
+ case B_STATE_EXPORTING:
+ if (b_port && remote && to_remote==remote)
+ {
+ /* remote export done */
+ state = B_STATE_REMOTE;
+ } else
+ {
+ /* bchannel is now exported, but we need bchannel back OR bchannel is not used anymore OR remote has changed, so reimport, to later export to new remote */
+ message_bchannel_to_join(remote, BCHANNEL_REMOVE, addr);
+ chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
+ add_trace("type", NULL, "remove");
+ add_trace("stack", "address", "%x", addr);
+ end_trace();
+ state = B_STATE_IMPORTING;
+ }
+ break;
+
+ default:
+ PERROR("Illegal event %d at state %d, please correct.\n", event, state);
+ }
+ break;
+
+ case B_EVENT_DROP:
+ if (!b_port)
FATAL("bchannel must be linked to a Port class\n");
+ mISDNport->b_remote[i] = 0;
switch(state)
{
case B_STATE_IDLE:
@@ -674,6 +793,7 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
break;
case B_STATE_ACTIVATING:
+ case B_STATE_EXPORTING:
/* do nothing because we must wait until bchanenl is active before deactivating */
break;
@@ -683,7 +803,18 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
state = B_STATE_DEACTIVATING;
break;
+ case B_STATE_REMOTE:
+ /* bchannel is exported, so we re-import */
+ message_bchannel_to_join(remote, BCHANNEL_REMOVE, addr);
+ chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
+ add_trace("type", NULL, "remove");
+ add_trace("stack", "address", "%x", addr);
+ end_trace();
+ state = B_STATE_IMPORTING;
+ break;
+
case B_STATE_DEACTIVATING:
+ case B_STATE_IMPORTING:
/* we may have taken an already deactivating bchannel, but do not require it anymore, so we do nothing */
break;
@@ -702,13 +833,24 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
case B_STATE_DEACTIVATING:
_bchannel_destroy(mISDNport, i);
state = B_STATE_IDLE;
- if (mISDNport->b_port[i])
+ if (b_port)
{
- /* bchannel is now deactivate, but is requied by Port class, so we reactivate */
- if (_bchannel_create(mISDNport, i))
+ /* bchannel is now deactivate, but is requied by Port class, so we reactivate / export */
+ if (remote)
{
- _bchannel_activate(mISDNport, i, 1);
- state = B_STATE_ACTIVATING;
+ message_bchannel_to_join(remote, BCHANNEL_ASSIGN, addr);
+ chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
+ add_trace("type", NULL, "assign");
+ add_trace("stack", "address", "%x", addr);
+ end_trace();
+ state = B_STATE_EXPORTING;
+ } else
+ {
+ if (_bchannel_create(mISDNport, i))
+ {
+ _bchannel_activate(mISDNport, i, 1);
+ state = B_STATE_ACTIVATING;
+ }
}
}
break;
@@ -718,6 +860,39 @@ void bchannel_event(struct mISDNport *mISDNport, int i, int event)
}
break;
+ case B_EVENT_IMPORTED:
+ switch(state)
+ {
+ case B_STATE_IMPORTING:
+ state = B_STATE_IDLE;
+ if (b_port)
+ {
+ /* bchannel is now imported, but is requied by Port class, so we reactivate / export */
+ if (remote)
+ {
+ message_bchannel_to_join(remote, BCHANNEL_ASSIGN, addr);
+ chan_trace_header(mISDNport, b_port, "MESSAGE_BCHANNEL (to remote application)", DIRECTION_NONE);
+ add_trace("type", NULL, "assign");
+ add_trace("stack", "address", "%x", addr);
+ end_trace();
+ state = B_STATE_EXPORTING;
+ } else
+ {
+ if (_bchannel_create(mISDNport, i))
+ {
+ _bchannel_activate(mISDNport, i, 1);
+ state = B_STATE_ACTIVATING;
+ }
+ }
+ }
+ break;
+
+ default:
+ /* ignore, because not assigned */
+ ;
+ }
+ break;
+
default:
PERROR("Illegal event %d, please correct.\n", event);
}
@@ -792,6 +967,7 @@ seize:
/* link Port */
p_m_mISDNport->b_port[i] = this;
+ p_m_mISDNport->b_remote[i] = p_m_exportremote;
p_m_b_index = i;
p_m_b_channel = channel;
p_m_b_exclusive = exclusive;
@@ -827,13 +1003,98 @@ void PmISDN::drop_bchannel(void)
PDEBUG(DEBUG_BCHANNEL, "PmISDN(%s) dropping bchannel\n", p_name);
if (p_m_mISDNport->b_state[p_m_b_index] != B_STATE_IDLE)
- bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DEACTIVATE);
+ bchannel_event(p_m_mISDNport, p_m_b_index, B_EVENT_DROP, 0);
p_m_mISDNport->b_port[p_m_b_index] = NULL;
+ p_m_mISDNport->b_remote[p_m_b_index] = 0;
p_m_b_index = -1;
p_m_b_channel = 0;
p_m_b_exclusive = 0;
}
+/* process bchannel export/import message from join */
+void message_bchannel_from_join(class JoinRemote *joinremote, int type, unsigned long addr)
+{
+ class Endpoint *epoint;
+ class Port *port;
+ class PmISDN *isdnport;
+ struct mISDNport *mISDNport;
+ int i, ii;
+
+ switch(type)
+ {
+ case BCHANNEL_REQUEST:
+ /* find the port object for the join object ref */
+ if (!(epoint = find_epoint_id(joinremote->j_epoint_id)))
+ {
+ PDEBUG(DEBUG_BCHANNEL, "join %d has no endpoint (anymore)\n", joinremote->j_serial);
+ return;
+ }
+ if (!epoint->ep_portlist)
+ {
+ PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore in portlist)\n", joinremote->j_serial);
+ return;
+ }
+ if (epoint->ep_portlist->next)
+ {
+ PERROR("join %d has enpoint %d with more than one port. this shall not happen to remote joins.\n", joinremote->j_serial, epoint->ep_serial);
+ }
+ if (!(port = find_port_id(epoint->ep_portlist->port_id)))
+ {
+ PDEBUG(DEBUG_BCHANNEL, "join %d has no port (anymore as object)\n", joinremote->j_serial);
+ return;
+ }
+ if (!((port->p_type&PORT_CLASS_MASK) != PORT_CLASS_mISDN))
+ {
+ PERROR("join %d has port %d not of mISDN type. This shall not happen.\n", joinremote->j_serial, port->p_serial);
+ }
+ isdnport = (class PmISDN *)port;
+
+ /* assign */
+ if (isdnport->p_m_exportremote)
+ {
+ PERROR("join %d recevied bchannel request from remote, but channel is already assinged.\n", joinremote->j_serial);
+ break;
+ }
+ chan_trace_header(isdnport->p_m_mISDNport, isdnport, "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
+ add_trace("type", NULL, "export request");
+ isdnport->p_m_exportremote = joinremote->j_serial;
+ if (isdnport->p_m_mISDNport && isdnport->p_m_b_index>=0)
+ bchannel_event(isdnport->p_m_mISDNport, isdnport->p_m_b_index, B_EVENT_EXPORTREQUEST, joinremote->j_serial);
+ end_trace();
+ break;
+
+ case BCHANNEL_ASSIGN_ACK:
+ case BCHANNEL_REMOVE_ACK:
+ /* find mISDNport for stack ID */
+ mISDNport = mISDNport_first;
+ while(mISDNport)
+ {
+ i = 0;
+ ii = mISDNport->b_num;
+ while(i < ii)
+ {
+ if (mISDNport->b_addr[i] == addr)
+ break;
+ i++;
+ }
+ if (i != ii)
+ break;
+ mISDNport = mISDNport->next;
+ }
+ /* mISDNport may now be set or NULL */
+
+ /* set */
+ chan_trace_header(mISDNport, mISDNport->b_port[i], "MESSAGE_BCHANNEL (from remote application)", DIRECTION_NONE);
+ add_trace("type", NULL, (type==BCHANNEL_ASSIGN_ACK)?"assign_ack":"remove_ack");
+ if (mISDNport && i>=0)
+ bchannel_event(mISDNport, i, (type==BCHANNEL_ASSIGN_ACK)?B_EVENT_EXPORTED:B_EVENT_IMPORTED, 0);
+ end_trace();
+ break;
+ default:
+ PERROR("received wrong bchannel message type %d from remote\n", type);
+ }
+}
+
/*
* handler
@@ -1815,7 +2076,7 @@ int mISDN_handler(void)
PERROR("unhandled b-establish (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
break;
}
- bchannel_event(mISDNport, i, B_EVENT_ACTIVATED);
+ bchannel_event(mISDNport, i, B_EVENT_ACTIVATED, 0);
break;
case PH_DEACTIVATE | INDICATION:
@@ -1835,7 +2096,7 @@ int mISDN_handler(void)
PERROR("unhandled b-release (prim 0x%x address 0x%x).\n", frm->prim, frm->addr);
break;
}
- bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED);
+ bchannel_event(mISDNport, i, B_EVENT_DEACTIVATED, 0);
break;
default:
diff --git a/mISDN.h b/mISDN.h
index db1a8cb..90ec032 100644
--- a/mISDN.h
+++ b/mISDN.h
@@ -9,20 +9,6 @@
** **
\*****************************************************************************/
-enum {
- B_STATE_IDLE,
- B_STATE_ACTIVATING,
- B_STATE_ACTIVE,
- B_STATE_DEACTIVATING,
-};
-
-enum {
- B_EVENT_ACTIVATE,
- B_EVENT_ACTIVATED,
- B_EVENT_DEACTIVATE,
- B_EVENT_DEACTIVATED,
-};
-
#define FROMUP_BUFFER_SIZE 1024
#define FROMUP_BUFFER_MASK 1023
@@ -53,10 +39,11 @@ struct mISDNport {
int d_stid;
int b_num; /* number of bchannels */
int b_reserved; /* number of bchannels reserved or in use */
- class PmISDN *b_port[128]; /* maximum number of ports shall be 128 due to S0 / E1 / special E1 */
+ class PmISDN *b_port[128]; /* bchannel assigned to port object */
int b_stid[128];
- int b_addr[128];
- int b_state[128]; /* state 0 = IDLE */
+ unsigned long b_addr[128];
+ int b_state[128]; /* statemachine, 0 = IDLE */
+ unsigned long b_remote[128]; /* if remote application requires bchannel */
int procids[128]; /* keep track of free ids */
int locally; /* local causes are sent as local causes not remote */
msg_queue_t downqueue; /* l4->l3 */
@@ -96,7 +83,8 @@ int stack2manager_nt(void *dat, void *arg);
int stack2manager_te(struct mISDNport *mISDNport, msg_t *msg);
void chan_trace_header(struct mISDNport *mISDNport, class PmISDN *port, char *msgtext, int direction);
void l1l2l3_trace_header(struct mISDNport *mISDNport, class PmISDN *port, unsigned long prim, int direction);
-void bchannel_event(struct mISDNport *mISDNport, int i, int event);
+void bchannel_event(struct mISDNport *mISDNport, int i, int event, unsigned long to_remote);
+void message_bchannel_from_join(class JoinRemote *joinremote, int type, unsigned long addr);
/* mISDN port classes */
@@ -158,6 +146,7 @@ class PmISDN : public Port
int p_m_hold; /* if port is on hold */
unsigned long p_m_timeout; /* timeout of timers */
time_t p_m_timer; /* start of timer */
+ unsigned char p_m_exportremote; /* join to export bchannel to */
int seize_bchannel(int channel, int exclusive); /* requests / reserves / links bchannels, but does not open it! */
void drop_bchannel(void);
diff --git a/message.h b/message.h
index d60c1b3..422ada1 100644
--- a/message.h
+++ b/message.h
@@ -125,6 +125,33 @@ enum { /* isdnsignal */
mISDNSIGNAL_DELAY, /* use delay or adaptive jitter */
};
+enum { /* bchannel assignment */
+ BCHANNEL_REQUEST, /* application requests bchannel */
+ BCHANNEL_ASSIGN, /* bchannel assigned by LCR */
+ BCHANNEL_ASSIGN_ACK, /* application acknowledges */
+ BCHANNEL_REMOVE, /* bchannel removed by LCR */
+ BCHANNEL_REMOVE_ACK, /* application acknowledges */
+};
+enum {
+ B_STATE_IDLE, /* not open */
+ B_STATE_ACTIVATING, /* DL_ESTABLISH sent */
+ B_STATE_ACTIVE, /* channel active */
+ B_STATE_DEACTIVATING, /* DL_RELEASE sent */
+ B_STATE_EXPORTING, /* BCHANNEL_ASSIGN sent */
+ 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 */
+};
+
+
/* call-info structure CALLER */
struct caller_info {
char id[32]; /* id of caller (user number) */
@@ -279,6 +306,7 @@ struct param_hello {
};
struct param_bchannel {
+ int type; /* BCHANNEL_* */
unsigned long addr; /* bchannel stack address */
};
@@ -359,8 +387,7 @@ 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_BCHANNEL, /* request/assign bchannel */
- MESSAGE_BCHANNEL_FREE, /* requests/assigns bchannel to be free */
+ MESSAGE_BCHANNEL, /* request/assign/remove bchannel */
MESSAGE_HELLO, /* hello message for remote application */
MESSAGE_NEWREF, /* special message to create and inform ref */
};
diff --git a/message.txt b/message.txt
index a78bba4..0c770a3 100644
--- a/message.txt
+++ b/message.txt
@@ -159,3 +159,34 @@ the endpoint may receive MESSAGE_RELEASE from a call but may NOT send it
to the port. the port MUST get a MESSAGE_DISCONNECT instead.
+REMOTE APPLICATION PROCEDURE
+----------------------------
+
+MESSAGE_NEWREF
+- is sent before outgoing setup may be sent
+- is received before outgoing setup may be sent
+- is received before incoming call
+
+MESSAGE_BCHANNEL
+- type BCHANNEL_REQUEST is sent to get the bchannel stack
+ the ref is required to find the corresponding port class
+- type BCHANNEL_ASSIGN is received, if channel is available, ACK must be sent
+ the ref is given with the bchannel stack.
+- type BCHANNEL_ASSIGN_ACK must be sent to acknowledge channel
+ the ref is 0, the stack address must be set to find corresponding channel
+- type BCHANNEL_REMOVE is received, if channel is not available anymore
+ the stack must then be release, the ACK must be sent.
+ the ref is given with the bchannel stack.
+- type BCHANNEL_REMOVE_ACK must be sent after releasing stack.
+ the ref is 0, the stack address must be set to find corresponding channel
+
+MESSAGE_RELEASE
+- will be received or sent to release call and ref.
+- also bchannel socket must be closed AND BCHANNEL_REMOVE_ACK must be sent!
+ the bchannel is in exported state until acked by the remote application.
+
+what happenes to channels that are not acked?
+-> one solution may be: they are blocked until the port is unloaded/unblocked.
+
+
+