Implement 3PTY bridge of two 'join's.
This commit is contained in:
parent
30224b43e2
commit
04fc928a2c
278
apppbx.cpp
278
apppbx.cpp
|
@ -2402,9 +2402,27 @@ void EndpointAppPBX::port_3pty(struct port_list *portlist, int message_type, uni
|
||||||
struct lcr_msg *message;
|
struct lcr_msg *message;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
rc = join_join();
|
#if 0
|
||||||
|
/* bridge for real */
|
||||||
|
if (param->threepty.begin)
|
||||||
|
rc = join_join();
|
||||||
|
else if (param->threepty.end)
|
||||||
|
rc = -ENOTSUP;
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
/* 3PTY bridge */
|
||||||
|
if (param->threepty.begin)
|
||||||
|
rc = join_3pty();
|
||||||
|
else if (param->threepty.end)
|
||||||
|
rc = split_3pty();
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_3PTY);
|
message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_3PTY);
|
||||||
message->param.threepty.begin = 1;
|
message->param.threepty.begin = param->threepty.begin;
|
||||||
|
message->param.threepty.end = param->threepty.end;
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
message->param.threepty.error = 1;
|
message->param.threepty.error = 1;
|
||||||
else
|
else
|
||||||
|
@ -3564,13 +3582,14 @@ int EndpointAppPBX::join_join(void)
|
||||||
{
|
{
|
||||||
#ifdef WITH_MISDN
|
#ifdef WITH_MISDN
|
||||||
struct lcr_msg *message;
|
struct lcr_msg *message;
|
||||||
struct join_relation *our_relation, *other_relation;
|
struct join_relation *add_relation, *remove_relation;
|
||||||
struct join_relation **our_relation_pointer, **other_relation_pointer;
|
struct join_relation **add_relation_pointer, **remove_relation_pointer;
|
||||||
class Join *our_join, *other_join;
|
class Join *our_join, *other_join, *add_join, *remove_join;
|
||||||
class JoinPBX *our_joinpbx, *other_joinpbx;
|
class JoinPBX *our_joinpbx, *other_joinpbx, *add_joinpbx, *remove_joinpbx;
|
||||||
class EndpointAppPBX *other_eapp; class Endpoint *temp_epoint;
|
class EndpointAppPBX *other_eapp, *remove_eapp;
|
||||||
class Port *our_port, *other_port;
|
class Port *our_port, *other_port;
|
||||||
class Pdss1 *our_pdss1, *other_pdss1;
|
class Pdss1 *our_pdss1, *other_pdss1;
|
||||||
|
class Endpoint *temp_epoint;
|
||||||
|
|
||||||
/* are we a candidate to join a join? */
|
/* are we a candidate to join a join? */
|
||||||
our_join = find_join_id(ea_endpoint->ep_join_id);
|
our_join = find_join_id(ea_endpoint->ep_join_id);
|
||||||
|
@ -3602,7 +3621,7 @@ int EndpointAppPBX::join_join(void)
|
||||||
}
|
}
|
||||||
our_pdss1 = (class Pdss1 *)our_port;
|
our_pdss1 = (class Pdss1 *)our_port;
|
||||||
|
|
||||||
/* find an endpoint that is on hold and has the same mISDNport that we are on */
|
/* find an endpoint that has the same mISDNport/ces that we are on */
|
||||||
other_eapp = apppbx_first;
|
other_eapp = apppbx_first;
|
||||||
while(other_eapp) {
|
while(other_eapp) {
|
||||||
if (other_eapp == this) {
|
if (other_eapp == this) {
|
||||||
|
@ -3658,58 +3677,75 @@ int EndpointAppPBX::join_join(void)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* now find out which is ACTIVE-IDLE and which is ACTIVE-HELD */
|
||||||
|
if (our_pdss1->p_m_hold && !other_pdss1->p_m_hold) {
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) our relation is on hold and other is active, so we move our relations to other relations\n", ea_endpoint->ep_serial);
|
||||||
|
remove_eapp = this;
|
||||||
|
remove_join = our_join;
|
||||||
|
remove_joinpbx = our_joinpbx;
|
||||||
|
add_join = other_join;
|
||||||
|
add_joinpbx = other_joinpbx;
|
||||||
|
} else {
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) our relation is active or other is on hold, so we move ohter relations to our relations\n", ea_endpoint->ep_serial);
|
||||||
|
remove_eapp = other_eapp;
|
||||||
|
remove_join = other_join;
|
||||||
|
remove_joinpbx = other_joinpbx;
|
||||||
|
add_join = our_join;
|
||||||
|
add_joinpbx = our_joinpbx;
|
||||||
|
}
|
||||||
|
|
||||||
/* remove relation to endpoint for join on hold */
|
/* remove relation to endpoint for join on hold */
|
||||||
other_relation = other_joinpbx->j_relation;
|
remove_relation = remove_joinpbx->j_relation;
|
||||||
other_relation_pointer = &other_joinpbx->j_relation;
|
remove_relation_pointer = &remove_joinpbx->j_relation;
|
||||||
while(other_relation) {
|
while(remove_relation) {
|
||||||
if (other_relation->epoint_id == other_eapp->ea_endpoint->ep_serial) {
|
if (remove_relation->epoint_id == remove_eapp->ea_endpoint->ep_serial) {
|
||||||
/* detach other endpoint on hold */
|
/* detach other endpoint */
|
||||||
*other_relation_pointer = other_relation->next;
|
*remove_relation_pointer = remove_relation->next;
|
||||||
FREE(other_relation, sizeof(struct join_relation));
|
FREE(remove_relation, sizeof(struct join_relation));
|
||||||
cmemuse--;
|
cmemuse--;
|
||||||
other_relation = *other_relation_pointer;
|
remove_relation = *remove_relation_pointer;
|
||||||
other_eapp->ea_endpoint->ep_join_id = 0;
|
remove_eapp->ea_endpoint->ep_join_id = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* change join/hold pointer of endpoint to the new join */
|
/* change join/hold pointer of endpoint to the new join */
|
||||||
temp_epoint = find_epoint_id(other_relation->epoint_id);
|
temp_epoint = find_epoint_id(remove_relation->epoint_id);
|
||||||
if (temp_epoint) {
|
if (temp_epoint) {
|
||||||
if (temp_epoint->ep_join_id == other_join->j_serial)
|
if (temp_epoint->ep_join_id == remove_join->j_serial)
|
||||||
temp_epoint->ep_join_id = our_join->j_serial;
|
temp_epoint->ep_join_id = add_join->j_serial;
|
||||||
}
|
}
|
||||||
|
|
||||||
other_relation_pointer = &other_relation->next;
|
remove_relation_pointer = &remove_relation->next;
|
||||||
other_relation = other_relation->next;
|
remove_relation = remove_relation->next;
|
||||||
}
|
}
|
||||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) endpoint on hold removed, other enpoints on join relinked (to our join).\n", ea_endpoint->ep_serial);
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) endpoint removed, other enpoints on join relinked.\n", ea_endpoint->ep_serial);
|
||||||
|
|
||||||
/* join call relations */
|
/* join call relations */
|
||||||
our_relation = our_joinpbx->j_relation;
|
add_relation = add_joinpbx->j_relation;
|
||||||
our_relation_pointer = &our_joinpbx->j_relation;
|
add_relation_pointer = &add_joinpbx->j_relation;
|
||||||
while(our_relation) {
|
while(add_relation) {
|
||||||
our_relation_pointer = &our_relation->next;
|
add_relation_pointer = &add_relation->next;
|
||||||
our_relation = our_relation->next;
|
add_relation = add_relation->next;
|
||||||
}
|
}
|
||||||
*our_relation_pointer = other_joinpbx->j_relation;
|
*add_relation_pointer = remove_joinpbx->j_relation;
|
||||||
other_joinpbx->j_relation = NULL;
|
remove_joinpbx->j_relation = NULL;
|
||||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) relations joined.\n", ea_endpoint->ep_serial);
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) relations joined.\n", ea_endpoint->ep_serial);
|
||||||
|
|
||||||
/* release endpoint on hold */
|
/* release endpoint */
|
||||||
message = message_create(other_joinpbx->j_serial, other_eapp->ea_endpoint->ep_serial, JOIN_TO_EPOINT, MESSAGE_RELEASE);
|
message = message_create(remove_joinpbx->j_serial, remove_eapp->ea_endpoint->ep_serial, JOIN_TO_EPOINT, MESSAGE_RELEASE);
|
||||||
message->param.disconnectinfo.cause = CAUSE_NORMAL; /* normal */
|
message->param.disconnectinfo.cause = CAUSE_NORMAL; /* normal */
|
||||||
message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
|
message->param.disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
|
||||||
message_put(message);
|
message_put(message);
|
||||||
|
|
||||||
/* if we are not a partyline, we get partyline state from other join */
|
/* if we are not a partyline, we get partyline state from other join */
|
||||||
our_joinpbx->j_partyline += other_joinpbx->j_partyline;
|
add_joinpbx->j_partyline += remove_joinpbx->j_partyline;
|
||||||
|
|
||||||
/* remove empty join */
|
/* remove empty join */
|
||||||
delete other_join;
|
delete remove_join;
|
||||||
PDEBUG(DEBUG_EPOINT, "EPOINT(%d)d-join completely removed!\n");
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d)join completely removed!\n", ea_endpoint->ep_serial);
|
||||||
|
|
||||||
/* mixer must update */
|
/* mixer must update */
|
||||||
trigger_work(&our_joinpbx->j_updatebridge);
|
trigger_work(&add_joinpbx->j_updatebridge);
|
||||||
|
|
||||||
/* we send a retrieve to that endpoint */
|
/* we send a retrieve to that endpoint */
|
||||||
// mixer will update the hold-state of the join and send it to the endpoints is changes
|
// mixer will update the hold-state of the join and send it to the endpoints is changes
|
||||||
|
@ -3720,6 +3756,176 @@ int EndpointAppPBX::join_join(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int EndpointAppPBX::join_3pty(void)
|
||||||
|
{
|
||||||
|
#ifdef WITH_MISDN
|
||||||
|
class Join *our_join, *other_join;
|
||||||
|
class JoinPBX *our_joinpbx, *other_joinpbx;
|
||||||
|
class EndpointAppPBX *other_eapp;
|
||||||
|
class Port *our_port, *other_port;
|
||||||
|
class Pdss1 *our_pdss1, *other_pdss1;
|
||||||
|
|
||||||
|
/* are we a candidate to join a join? */
|
||||||
|
our_join = find_join_id(ea_endpoint->ep_join_id);
|
||||||
|
if (!our_join) {
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: our join doesn't exist anymore.\n", ea_endpoint->ep_serial);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
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 -1;
|
||||||
|
}
|
||||||
|
our_joinpbx = (class JoinPBX *)our_join;
|
||||||
|
if (!ea_endpoint->ep_portlist) {
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: we have no port.\n", ea_endpoint->ep_serial);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (!e_ext.number[0]) {
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: we are not internal extension.\n", ea_endpoint->ep_serial);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
our_port = find_port_id(ea_endpoint->ep_portlist->port_id);
|
||||||
|
if (!our_port) {
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: our port doesn't exist anymore.\n", ea_endpoint->ep_serial);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ((our_port->p_type & PORT_CLASS_mISDN_MASK) != PORT_CLASS_DSS1) {
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: our port is not isdn.\n", ea_endpoint->ep_serial);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
our_pdss1 = (class Pdss1 *)our_port;
|
||||||
|
|
||||||
|
/* find an endpoint that has the same mISDNport/ces that we are on */
|
||||||
|
other_eapp = apppbx_first;
|
||||||
|
while(other_eapp) {
|
||||||
|
if (other_eapp == this) {
|
||||||
|
other_eapp = other_eapp->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) comparing other endpoint candiate: (ep%d) terminal='%s' port=%s join=%d.\n", ea_endpoint->ep_serial, other_eapp->ea_endpoint->ep_serial, other_eapp->e_ext.number, (other_eapp->ea_endpoint->ep_portlist)?"YES":"NO", other_eapp->ea_endpoint->ep_join_id);
|
||||||
|
if (other_eapp->e_ext.number[0] /* has terminal */
|
||||||
|
&& other_eapp->ea_endpoint->ep_portlist /* has port */
|
||||||
|
&& other_eapp->ea_endpoint->ep_join_id) { /* has join */
|
||||||
|
other_port = find_port_id(other_eapp->ea_endpoint->ep_portlist->port_id);
|
||||||
|
if (other_port) { /* port still exists */
|
||||||
|
if (other_port->p_type==PORT_TYPE_DSS1_NT_OUT
|
||||||
|
|| other_port->p_type==PORT_TYPE_DSS1_NT_IN) { /* port is isdn nt-mode */
|
||||||
|
other_pdss1 = (class Pdss1 *)other_port;
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) comparing other endpoint's port is of type isdn! comparing our portnum=%d with other's portnum=%d hold=%s ces=%d\n", ea_endpoint->ep_serial, our_pdss1->p_m_mISDNport->portnum, other_pdss1->p_m_mISDNport->portnum, (other_pdss1->p_m_hold)?"YES":"NO", other_pdss1->p_m_d_ces);
|
||||||
|
if (1 //other_pdss1->p_m_hold /* port is on hold */
|
||||||
|
&& other_pdss1->p_m_mISDNport == our_pdss1->p_m_mISDNport /* same isdn interface */
|
||||||
|
&& other_pdss1->p_m_d_ces == our_pdss1->p_m_d_ces) /* same tei+sapi */
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) comparing other endpoint's port is of other type!\n", ea_endpoint->ep_serial);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) comparing other endpoint's port doesn't exist enymore.\n", ea_endpoint->ep_serial);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
other_eapp = other_eapp->next;
|
||||||
|
}
|
||||||
|
if (!other_eapp) {
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: no other endpoint on same isdn terminal.\n", ea_endpoint->ep_serial);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) port with same terminal found.\n", ea_endpoint->ep_serial);
|
||||||
|
|
||||||
|
/* if we have the same join */
|
||||||
|
if (other_eapp->ea_endpoint->ep_join_id == ea_endpoint->ep_join_id) {
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: we and the other have the same join.\n", ea_endpoint->ep_serial);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
other_join = find_join_id(other_eapp->ea_endpoint->ep_join_id);
|
||||||
|
if (!other_join) {
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: other join doesn't exist anymore.\n", ea_endpoint->ep_serial);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
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 -1;
|
||||||
|
}
|
||||||
|
other_joinpbx = (class JoinPBX *)other_join;
|
||||||
|
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 -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (our_joinpbx->j_3pty) {
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: our join already doing 3PTY.\n", ea_endpoint->ep_serial);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (other_joinpbx->j_3pty) {
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: other join already doing 3PTY.\n", ea_endpoint->ep_serial);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set 3PTY bridge */
|
||||||
|
other_joinpbx->j_3pty = our_joinpbx->j_serial;
|
||||||
|
our_joinpbx->j_3pty = other_joinpbx->j_serial;
|
||||||
|
|
||||||
|
/* mixer must update */
|
||||||
|
trigger_work(&our_joinpbx->j_updatebridge);
|
||||||
|
trigger_work(&other_joinpbx->j_updatebridge);
|
||||||
|
|
||||||
|
/* we send a retrieve to that endpoint */
|
||||||
|
// mixer will update the hold-state of the join and send it to the endpoints is changes
|
||||||
|
#else
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: no mISDN support anyway.\n", ea_endpoint->ep_serial);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EndpointAppPBX::split_3pty(void)
|
||||||
|
{
|
||||||
|
#ifdef WITH_MISDN
|
||||||
|
class Join *our_join, *other_join;
|
||||||
|
class JoinPBX *our_joinpbx, *other_joinpbx;
|
||||||
|
|
||||||
|
/* are we a candidate to join a join? */
|
||||||
|
our_join = find_join_id(ea_endpoint->ep_join_id);
|
||||||
|
if (!our_join) {
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot split: our join doesn't exist anymore.\n", ea_endpoint->ep_serial);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (our_join->j_type != JOIN_TYPE_PBX) {
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot split: join is not a pbx join.\n", ea_endpoint->ep_serial);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
our_joinpbx = (class JoinPBX *)our_join;
|
||||||
|
|
||||||
|
if (!our_joinpbx->j_3pty) {
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot split: we don't have a 3PTY.\n", ea_endpoint->ep_serial);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
other_join = find_join_id(our_joinpbx->j_3pty);
|
||||||
|
if (!other_join) {
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot split: other join doesn't exist anymore.\n", ea_endpoint->ep_serial);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (other_join->j_type != JOIN_TYPE_PBX) {
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot split: join is not a pbx join.\n", ea_endpoint->ep_serial);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
other_joinpbx = (class JoinPBX *)other_join;
|
||||||
|
|
||||||
|
our_joinpbx->j_3pty = 0;
|
||||||
|
other_joinpbx->j_3pty = 0;
|
||||||
|
|
||||||
|
/* mixer must update */
|
||||||
|
trigger_work(&our_joinpbx->j_updatebridge);
|
||||||
|
trigger_work(&other_joinpbx->j_updatebridge);
|
||||||
|
|
||||||
|
/* we send a retrieve to that endpoint */
|
||||||
|
// mixer will update the hold-state of the join and send it to the endpoints is changes
|
||||||
|
#else
|
||||||
|
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot split: no mISDN support anyway.\n", ea_endpoint->ep_serial);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* check if we have an external call
|
/* check if we have an external call
|
||||||
* this is used to check for encryption ability
|
* this is used to check for encryption ability
|
||||||
|
|
2
apppbx.h
2
apppbx.h
|
@ -309,6 +309,8 @@ class EndpointAppPBX : public EndpointApp
|
||||||
/* facility function */
|
/* facility function */
|
||||||
void pick_join(char *extension);
|
void pick_join(char *extension);
|
||||||
int join_join(void);
|
int join_join(void);
|
||||||
|
int join_3pty(void);
|
||||||
|
int split_3pty(void);
|
||||||
void encrypt_shared(void);
|
void encrypt_shared(void);
|
||||||
void encrypt_keyex(void);
|
void encrypt_keyex(void);
|
||||||
void encrypt_off(void);
|
void encrypt_off(void);
|
||||||
|
|
56
joinpbx.cpp
56
joinpbx.cpp
|
@ -226,6 +226,7 @@ JoinPBX::JoinPBX(class Endpoint *epoint) : Join()
|
||||||
j_pid = getpid();
|
j_pid = getpid();
|
||||||
j_partyline = 0;
|
j_partyline = 0;
|
||||||
j_partyline_jingle = 0;
|
j_partyline_jingle = 0;
|
||||||
|
j_3pty = 0;
|
||||||
j_multicause = 0;
|
j_multicause = 0;
|
||||||
j_multilocation = 0;
|
j_multilocation = 0;
|
||||||
memset(&j_updatebridge, 0, sizeof(j_updatebridge));
|
memset(&j_updatebridge, 0, sizeof(j_updatebridge));
|
||||||
|
@ -261,6 +262,19 @@ JoinPBX::~JoinPBX()
|
||||||
relation = rtemp;
|
relation = rtemp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* remove 3PTY from other join */
|
||||||
|
if (j_3pty) {
|
||||||
|
class Join *join;
|
||||||
|
class JoinPBX *joinpbx;
|
||||||
|
|
||||||
|
join = find_join_id(j_3pty);
|
||||||
|
if (join && join->j_type == JOIN_TYPE_PBX) {
|
||||||
|
joinpbx = (class JoinPBX *)join;
|
||||||
|
joinpbx->j_3pty = 0;
|
||||||
|
trigger_work(&joinpbx->j_updatebridge);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
del_work(&j_updatebridge);
|
del_work(&j_updatebridge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,12 +299,21 @@ void JoinPBX::bridge(void)
|
||||||
class Endpoint *epoint;
|
class Endpoint *epoint;
|
||||||
struct port_list *portlist;
|
struct port_list *portlist;
|
||||||
class Port *port;
|
class Port *port;
|
||||||
|
unsigned int bridge_id;
|
||||||
#ifdef DEBUG_COREBRIDGE
|
#ifdef DEBUG_COREBRIDGE
|
||||||
int allmISDN = 0; // never set for debug purpose
|
int allmISDN = 0; // never set for debug purpose
|
||||||
#else
|
#else
|
||||||
int allmISDN = 1; // set until a non-mISDN relation is found
|
int allmISDN = 1; // set until a non-mISDN relation is found
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* bridge id is the serial of join
|
||||||
|
* if we have a 3pty with another join, we always use the lowest brigde id.
|
||||||
|
* this way we use common ids, so both joins share same bridge */
|
||||||
|
if (j_3pty && j_3pty < j_serial)
|
||||||
|
bridge_id = j_3pty;
|
||||||
|
else
|
||||||
|
bridge_id = j_serial;
|
||||||
|
|
||||||
relation = j_relation;
|
relation = j_relation;
|
||||||
while(relation) {
|
while(relation) {
|
||||||
/* count all relations */
|
/* count all relations */
|
||||||
|
@ -348,6 +371,8 @@ void JoinPBX::bridge(void)
|
||||||
numconnect ++;
|
numconnect ++;
|
||||||
|
|
||||||
/* remove unconnected parties from conference, also remove remotely disconnected parties so conference will not be disturbed. */
|
/* remove unconnected parties from conference, also remove remotely disconnected parties so conference will not be disturbed. */
|
||||||
|
|
||||||
|
/* mISDN */
|
||||||
if (relation->channel_state == 1
|
if (relation->channel_state == 1
|
||||||
&& relation->rx_state != NOTIFY_STATE_HOLD
|
&& relation->rx_state != NOTIFY_STATE_HOLD
|
||||||
&& relation->rx_state != NOTIFY_STATE_SUSPEND
|
&& relation->rx_state != NOTIFY_STATE_SUSPEND
|
||||||
|
@ -355,7 +380,7 @@ void JoinPBX::bridge(void)
|
||||||
&& allmISDN) { // no conf if any member is not mISDN
|
&& allmISDN) { // no conf if any member is not mISDN
|
||||||
message = message_create(j_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.message = mISDNSIGNAL_CONF;
|
||||||
message->param.mISDNsignal.conf = j_serial<<16 | j_pid;
|
message->param.mISDNsignal.conf = (bridge_id << 16) | j_pid;
|
||||||
PDEBUG(DEBUG_JOIN, "join%d EP%d +on+ id: 0x%08x\n", j_serial, relation->epoint_id, message->param.mISDNsignal.conf);
|
PDEBUG(DEBUG_JOIN, "join%d EP%d +on+ id: 0x%08x\n", j_serial, relation->epoint_id, message->param.mISDNsignal.conf);
|
||||||
message_put(message);
|
message_put(message);
|
||||||
} else {
|
} else {
|
||||||
|
@ -366,28 +391,35 @@ void JoinPBX::bridge(void)
|
||||||
message_put(message);
|
message_put(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* core bridge */
|
||||||
* Bridge between port instances if:
|
if (relation->channel_state == 1
|
||||||
* - two or more relations
|
&& relation->rx_state != NOTIFY_STATE_HOLD
|
||||||
* - one or all are not mISDN
|
&& relation->rx_state != NOTIFY_STATE_SUSPEND
|
||||||
*/
|
&& relations>1 // no bridge with one member
|
||||||
message = message_create(j_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_BRIDGE);
|
&& !allmISDN) { // no bridge if all members are mISDN
|
||||||
message->param.bridge_id = (relations>=2 && !allmISDN) ? j_serial : 0;
|
message = message_create(j_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_BRIDGE);
|
||||||
PDEBUG(DEBUG_JOIN, "join%u EP%u requests bridge=%u\n", j_serial, relation->epoint_id, message->param.bridge_id);
|
message->param.bridge_id = bridge_id;
|
||||||
message_put(message);
|
PDEBUG(DEBUG_JOIN, "join%u EP%u requests bridge=%u\n", j_serial, relation->epoint_id, bridge_id);
|
||||||
|
message_put(message);
|
||||||
|
} else {
|
||||||
|
message = message_create(j_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_BRIDGE);
|
||||||
|
message->param.bridge_id = 0;
|
||||||
|
PDEBUG(DEBUG_JOIN, "join%u EP%u drop bridge=%u\n", j_serial, relation->epoint_id, bridge_id);
|
||||||
|
message_put(message);
|
||||||
|
}
|
||||||
|
|
||||||
relation = relation->next;
|
relation = relation->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* two people just exchange their states */
|
/* two people just exchange their states */
|
||||||
if (relations==2 && !j_partyline) {
|
if (!j_3pty && relations==2 && !j_partyline) {
|
||||||
PDEBUG(DEBUG_JOIN, "join%d 2 relations / no partyline\n", j_serial);
|
PDEBUG(DEBUG_JOIN, "join%d 2 relations / no partyline\n", j_serial);
|
||||||
relation = j_relation;
|
relation = j_relation;
|
||||||
relation->tx_state = notify_state_change(j_serial, relation->epoint_id, relation->tx_state, relation->next->rx_state);
|
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);
|
relation->next->tx_state = notify_state_change(j_serial, relation->next->epoint_id, relation->next->tx_state, relation->rx_state);
|
||||||
} else
|
} else
|
||||||
/* one member in a join, so we put her on hold */
|
/* one member in a join, so we put her on hold */
|
||||||
if ((relations==1 || numconnect==1)/* && !j_partyline_jingle*/) {
|
if (!j_3pty && (relations==1 || numconnect==1)/* && !j_partyline_jingle*/) {
|
||||||
PDEBUG(DEBUG_JOIN, "join%d 1 member or only 1 connected, put on hold\n", j_serial);
|
PDEBUG(DEBUG_JOIN, "join%d 1 member or only 1 connected, put on hold\n", j_serial);
|
||||||
relation = j_relation;
|
relation = j_relation;
|
||||||
while(relation) {
|
while(relation) {
|
||||||
|
|
|
@ -65,6 +65,8 @@ class JoinPBX : public Join
|
||||||
int j_partyline; /* if set, join is conference room */
|
int j_partyline; /* if set, join is conference room */
|
||||||
int j_partyline_jingle; /* also play jingle on join/leave */
|
int j_partyline_jingle; /* also play jingle on join/leave */
|
||||||
|
|
||||||
|
unsigned int j_3pty; /* other join if a 3pty-bridge is requested */
|
||||||
|
|
||||||
void bridge(void);
|
void bridge(void);
|
||||||
void remove_relation(struct join_relation *relation);
|
void remove_relation(struct join_relation *relation);
|
||||||
struct join_relation *add_relation(void);
|
struct join_relation *add_relation(void);
|
||||||
|
|
|
@ -387,6 +387,13 @@ int debug_join(struct admin_message *msg, struct admin_message *m, int line, int
|
||||||
color(white);
|
color(white);
|
||||||
SPRINT(buffer,"JOIN(%d)", join);
|
SPRINT(buffer,"JOIN(%d)", join);
|
||||||
addstr(buffer);
|
addstr(buffer);
|
||||||
|
if (m[i].u.j.threepty) {
|
||||||
|
color(cyan);
|
||||||
|
addstr(" 3PTY->");
|
||||||
|
color(white);
|
||||||
|
SPRINT(buffer, "%d\n", m[i].u.j.threepty);
|
||||||
|
addstr(buffer);
|
||||||
|
}
|
||||||
if (m[i].u.j.partyline) {
|
if (m[i].u.j.partyline) {
|
||||||
color(cyan);
|
color(cyan);
|
||||||
addstr(" partyline=");
|
addstr(" partyline=");
|
||||||
|
|
|
@ -95,6 +95,7 @@ struct admin_response_join {
|
||||||
unsigned int serial; /* join serial number */
|
unsigned int serial; /* join serial number */
|
||||||
char remote[32]; /* remote application name */
|
char remote[32]; /* remote application name */
|
||||||
unsigned int partyline;
|
unsigned int partyline;
|
||||||
|
unsigned int threepty;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct admin_response_epoint {
|
struct admin_response_epoint {
|
||||||
|
|
|
@ -957,8 +957,10 @@ int admin_state(struct admin_queue **responsep)
|
||||||
/* serial */
|
/* serial */
|
||||||
response->am[num].u.j.serial = join->j_serial;
|
response->am[num].u.j.serial = join->j_serial;
|
||||||
/* partyline */
|
/* partyline */
|
||||||
if (join->j_type == JOIN_TYPE_PBX)
|
if (join->j_type == JOIN_TYPE_PBX) {
|
||||||
response->am[num].u.j.partyline = ((class JoinPBX *)join)->j_partyline;
|
response->am[num].u.j.partyline = ((class JoinPBX *)join)->j_partyline;
|
||||||
|
response->am[num].u.j.threepty = ((class JoinPBX *)join)->j_3pty;
|
||||||
|
}
|
||||||
/* */
|
/* */
|
||||||
join = join->next;
|
join = join->next;
|
||||||
num++;
|
num++;
|
||||||
|
|
Loading…
Reference in New Issue