+ delete remove_join;
+ PDEBUG(DEBUG_EPOINT, "EPOINT(%d)join completely removed!\n", ea_endpoint->ep_serial);
+
+ /* mixer must update */
+ trigger_work(&add_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::join_3pty_dss1(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::join_3pty_fxs(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 Pfxs *our_fxs, *other_fxs;
+
+ /* 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_POTS_MASK) != PORT_CLASS_POTS_FXS) {
+ PDEBUG(DEBUG_EPOINT, "EPOINT(%d) cannot join: our port is not FXS pots.\n", ea_endpoint->ep_serial);
+ return -1;
+ }
+ our_fxs = (class Pfxs *)our_port;
+
+ /* find an endpoint that has the same mISDNport 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_POTS_FXS_OUT
+ || other_port->p_type==PORT_TYPE_POTS_FXS_IN) { /* port is isdn nt-mode */
+ other_fxs = (class Pfxs *)other_port;
+ PDEBUG(DEBUG_EPOINT, "EPOINT(%d) comparing other endpoint's port is of type FXS! comparing our portnum=%d with other's portnum=%d hold=%s state=%d\n", ea_endpoint->ep_serial, our_fxs->p_m_mISDNport->portnum, other_fxs->p_m_mISDNport->portnum, (other_fxs->p_m_hold)?"YES":"NO", other_fxs->p_state);
+ if (1 //other_fxs->p_m_hold /* port is on hold */
+ && other_fxs->p_m_mISDNport == our_fxs->p_m_mISDNport) /* same pots interface */
+ 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 FXS 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;