X-Git-Url: http://git.eversberg.eu/gitweb.cgi?p=lcr.git;a=blobdiff_plain;f=joinpbx.cpp;h=6e995f3d2bb17a4cac6c248ade5b25a5416d20c9;hp=4b0654013d49121edd05587601627a46c6d1c3d9;hb=7440c9a44d71ee10d1915d604ff8a34fc42d24e4;hpb=8bb49ccb7b3eba0a3f20d3b097541304b3580f70 diff --git a/joinpbx.cpp b/joinpbx.cpp index 4b06540..6e995f3 100644 --- a/joinpbx.cpp +++ b/joinpbx.cpp @@ -226,6 +226,7 @@ JoinPBX::JoinPBX(class Endpoint *epoint) : Join() j_pid = getpid(); j_partyline = 0; j_partyline_jingle = 0; + j_3pty = 0; j_multicause = 0; j_multilocation = 0; memset(&j_updatebridge, 0, sizeof(j_updatebridge)); @@ -261,6 +262,19 @@ JoinPBX::~JoinPBX() 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); } @@ -285,12 +299,21 @@ void JoinPBX::bridge(void) class Endpoint *epoint; struct port_list *portlist; class Port *port; + unsigned int bridge_id; #ifdef DEBUG_COREBRIDGE int allmISDN = 0; // never set for debug purpose #else int allmISDN = 1; // set until a non-mISDN relation is found #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; while(relation) { /* count all relations */ @@ -348,6 +371,8 @@ void JoinPBX::bridge(void) numconnect ++; /* remove unconnected parties from conference, also remove remotely disconnected parties so conference will not be disturbed. */ + + /* mISDN */ if (relation->channel_state == 1 && relation->rx_state != NOTIFY_STATE_HOLD && relation->rx_state != NOTIFY_STATE_SUSPEND @@ -355,7 +380,7 @@ void JoinPBX::bridge(void) && allmISDN) { // no conf if any member is not mISDN message = message_create(j_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_mISDNSIGNAL); 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); message_put(message); } else { @@ -366,30 +391,35 @@ void JoinPBX::bridge(void) message_put(message); } - /* - * request data from endpoint/port if: - * - two relations - * - any without mISDN - * in this case we bridge - */ - message = message_create(j_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_mISDNSIGNAL); - message->param.mISDNsignal.message = mISDNSIGNAL_JOINDATA; - message->param.mISDNsignal.joindata = (relations==2 && !allmISDN); - PDEBUG(DEBUG_JOIN, "join%d EP%d set joindata=%d\n", j_serial, relation->epoint_id, message->param.mISDNsignal.joindata); - message_put(message); + /* core bridge */ + if (relation->channel_state == 1 + && relation->rx_state != NOTIFY_STATE_HOLD + && relation->rx_state != NOTIFY_STATE_SUSPEND + && relations>1 // no bridge with one member + && !allmISDN) { // no bridge if all members are mISDN + message = message_create(j_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_BRIDGE); + message->param.bridge_id = bridge_id; + 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; } /* 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); relation = j_relation; relation->tx_state = notify_state_change(j_serial, relation->epoint_id, relation->tx_state, relation->next->rx_state); relation->next->tx_state = notify_state_change(j_serial, relation->next->epoint_id, relation->next->tx_state, relation->rx_state); } else /* one member in a join, so we put her on hold */ - if ((relations==1 || numconnect==1)/* && !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); relation = j_relation; while(relation) { @@ -413,43 +443,6 @@ void JoinPBX::bridge(void) } } -/* - * bridging is only possible with two connected endpoints - */ -void JoinPBX::bridge_data(unsigned int epoint_from, struct join_relation *relation_from, union parameter *param) -{ - struct join_relation *relation_to; - - /* if we are alone */ - if (!j_relation->next) - return; - - /* if we are more than two */ - if (j_relation->next->next) - return; - - /* skip if source endpoint has NOT audio mode CONNECT */ - if (relation_from->channel_state != 1) - return; - - /* get destination relation */ - relation_to = j_relation; - if (relation_to == relation_from) { - /* oops, we are the first, so destination is: */ - relation_to = relation_to->next; - } - - /* skip if destination endpoint has NOT audio mode CONNECT */ - if (relation_to->channel_state != 1) - return; - - /* now we may send our data to the endpoint where it - * will be delivered to the port - */ -//printf("from %d, to %d\n", relation_from->epoint_id, relation_to->epoint_id); - message_forward(j_serial, relation_to->epoint_id, JOIN_TO_EPOINT, param); -} - /* release join from endpoint * if the join has two relations, all relations are freed and the join will be * destroyed @@ -538,9 +531,6 @@ int joinpbx_countrelations(unsigned int join_id) if (!join) return(0); - if (join->j_type == JOIN_TYPE_REMOTE) - return(2); - if (join->j_type != JOIN_TYPE_PBX) return(0); joinpbx = (class JoinPBX *)join; @@ -651,7 +641,7 @@ void JoinPBX::message_epoint(unsigned int epoint_id, int message_type, union par // joinpbx_debug(join,"Join::message_epoint"); // } if (options.deb & DEBUG_JOIN) { - if (message_type != MESSAGE_DATA) { + if (message_type) { cl = join_first; while(cl) { if (cl->j_type == JOIN_TYPE_PBX) @@ -731,7 +721,7 @@ void JoinPBX::message_epoint(unsigned int epoint_id, int message_type, union par switch(message_type) { /* process audio path message */ case MESSAGE_AUDIOPATH: - PDEBUG(DEBUG_JOIN, "join received channel message: %d.\n", param->audiopath); + PDEBUG(DEBUG_JOIN, "join received channel message: audiopath=%d, current relation's channel_state=%d\n", param->audiopath, relation->channel_state); if (relation->channel_state != param->audiopath) { relation->channel_state = param->audiopath; trigger_work(&j_updatebridge); @@ -772,12 +762,6 @@ void JoinPBX::message_epoint(unsigned int epoint_id, int message_type, union par } return; - /* audio data */ - case MESSAGE_DATA: - /* now send audio data to the other endpoint */ - bridge_data(epoint_id, relation, param); - return; - /* relations sends a connect */ case MESSAGE_CONNECT: /* outgoing setup type becomes connected */ @@ -963,8 +947,7 @@ int JoinPBX::out_setup(unsigned int epoint_id, int message_type, union parameter epoint = new Endpoint(0, j_serial); if (!epoint) FATAL("No memory for Endpoint instance\n"); - if (!(epoint->ep_app = new DEFAULT_ENDPOINT_APP(epoint, 1))) // outgoing - FATAL("No memory for Endpoint Application instance\n"); + epoint->ep_app = new_endpointapp(epoint, 1, EAPP_TYPE_PBX); // outgoing relation->epoint_id = epoint->ep_serial; /* send setup message to new endpoint */ //printf("JOLLY DEBUG: %d\n",join_countrelations(j_serial));