added exporting/importing bchannel stacks to the remote application
This commit is contained in:
parent
0a0643e3a5
commit
cbe9d412a3
|
@ -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])
|
||||
{
|
||||
|
|
|
@ -107,7 +107,7 @@ void free_connection(struct admin_list *admin)
|
|||
memset(¶m, 0, sizeof(param));
|
||||
param.disconnectinfo.cause = CAUSE_OUTOFORDER;
|
||||
param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
|
||||
((class JoinRemote *)join)->message_remote(0, MESSAGE_RELEASE, ¶m);
|
||||
((class JoinRemote *)join)->message_remote(MESSAGE_RELEASE, ¶m);
|
||||
/* 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);
|
||||
}
|
||||
|
|
75
apppbx.cpp
75
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);
|
||||
|
|
20
dss1.cpp
20
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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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(¶m, 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(¶m, 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, ¶m)<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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
305
mISDN.cpp
305
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:
|
||||
|
|
25
mISDN.h
25
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);
|
||||
|
|
31
message.h
31
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 */
|
||||
};
|
||||
|
|
31
message.txt
31
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.
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue