PDEBUG(DEBUG_JOIN, "end\n");
}
+int update_bridge(struct lcr_work *work, void *instance, int index);
/*
* constructor for a new join
j_dialed[0] = '\0';
j_todial[0] = '\0';
j_pid = getpid();
- j_updatebridge = 0;
j_partyline = 0;
j_partyline_jingle = 0;
j_multicause = 0;
j_multilocation = 0;
+ memset(&j_updatebridge, 0, sizeof(j_updatebridge));
+ add_work(&j_updatebridge, update_bridge, this, 0);
/* initialize a relation only to the calling interface */
relation = j_relation = (struct join_relation *)MALLOC(sizeof(struct join_relation));
cmemuse--;
relation = rtemp;
}
+
+ del_work(&j_updatebridge);
}
/* bridge sets the audio flow of all bchannels assiociated to 'this' join
* also it changes and notifies active/hold/conference states
*/
+int update_bridge(struct lcr_work *work, void *instance, int index)
+{
+ class JoinPBX *joinpbx = (class JoinPBX *)instance;
+
+ joinpbx->bridge();
+
+ return 0;
+}
+
void JoinPBX::bridge(void)
{
struct join_relation *relation;
}
/*
- * request data from endpoint/port if:
+ * Bridge between port instances if:
* - two relations
- * - any without mISDN
- * in this case we bridge
+ * - one or all are not mISDN
*/
- 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 = message_create(j_serial, relation->epoint_id, JOIN_TO_EPOINT, MESSAGE_BRIDGE);
+ message->param.bridge_id = (relations==2 && !allmISDN) ? j_serial : 0;
+ PDEBUG(DEBUG_JOIN, "join%u EP%u requests bridge=%u\n", j_serial, relation->epoint_id, message->param.bridge_id);
message_put(message);
relation = relation->next;
}
}
-/*
- * 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
/* remove from bridge */
if (relation->channel_state != 0) {
relation->channel_state = 0;
- j_updatebridge = 1; /* update bridge flag */
+ trigger_work(&j_updatebridge);
// note: if join is not released, bridge must be updated
}
// 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)
SPRINT(message->param.connectinfo.id, "%d", j_partyline);
message->param.connectinfo.ntype = INFO_NTYPE_UNKNOWN;
message_put(message);
- j_updatebridge = 1; /* update bridge flag */
+ trigger_work(&j_updatebridge);
if (j_partyline_jingle)
play_jingle(1);
break;
PDEBUG(DEBUG_JOIN, "join received channel message: %d.\n", param->audiopath);
if (relation->channel_state != param->audiopath) {
relation->channel_state = param->audiopath;
- j_updatebridge = 1; /* update bridge flag */
+ trigger_work(&j_updatebridge);
if (options.deb & DEBUG_JOIN)
joinpbx_debug(this, "Join::message_epoint{after setting new channel state}");
}
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;
- j_updatebridge = 1; /* update bridge flag */
+ trigger_work(&j_updatebridge);
if (options.deb & DEBUG_JOIN)
joinpbx_debug(this, "Join::message_epoint{after setting new channel state}");
}
new_state = track_notify(relation->rx_state, param->notifyinfo.notify);
if (new_state != relation->rx_state) {
relation->rx_state = new_state;
- j_updatebridge = 1;
+ trigger_work(&j_updatebridge);
if (options.deb & DEBUG_JOIN)
joinpbx_debug(this, "Join::message_epoint{after setting new rx state}");
}
}
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 */
switch(message_type) {
case MESSAGE_SETUP:
if (param->setup.dialinginfo.itype == INFO_ITYPE_ISDN_EXTENSION) {
- numbers = param->setup.dialinginfo.id;
- while((number = strsep(&numbers, ","))) {
- if (out_setup(epoint_id, message_type, param, number, NULL))
- return; // join destroyed
+ /* in case of keypad */
+ numbers = param->setup.dialinginfo.keypad;
+ if (numbers[0]) {
+ while((number = strsep(&numbers, ","))) {
+ if (out_setup(epoint_id, message_type, param, NULL, number))
+ return; // join destroyed
+ }
+ /* after keypad finish dialing */
+ break;
}
+ /* dialed number */
numbers = param->setup.dialinginfo.id;
while((number = strsep(&numbers, ","))) {
- if (out_setup(epoint_id, message_type, param, NULL, number))
+ if (out_setup(epoint_id, message_type, param, number, NULL))
return; // join destroyed
}
break;
}
- if (out_setup(epoint_id, message_type, param, NULL, NULL))
+ if (out_setup(epoint_id, message_type, param, param->setup.dialinginfo.id, param->setup.dialinginfo.keypad))
return; // join destroyed
break;
}
-/* join process is called from the main loop
- * it processes the current calling state.
- * returns 0 if join nothing was done
- */
-int JoinPBX::handler(void)
-{
-// struct join_relation *relation;
-// char dialing[32][32];
-// int port[32];
-// int found;
-// int i, j;
-// char *p;
-
- /* the bridge must be updated */
- if (j_updatebridge) {
- bridge();
- j_updatebridge = 0;
- return(1);
- }
-
- return(0);
-}
-
-
int track_notify(int oldstate, int notify)
{
int newstate = oldstate;
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));
memcpy(&message->param, param, sizeof(union parameter));
if (newnumber)
SCPY(message->param.setup.dialinginfo.id, newnumber);
+ else
+ message->param.setup.dialinginfo.id[0] = '\0';
if (newkeypad)
SCPY(message->param.setup.dialinginfo.keypad, newkeypad);
+ else
+ message->param.setup.dialinginfo.keypad[0] = '\0';
PDEBUG(DEBUG_JOIN, "setup message sent to ep %d with number='%s' keypad='%s'.\n", relation->epoint_id, message->param.setup.dialinginfo.id, message->param.setup.dialinginfo.keypad);
message_put(message);
return(0);