summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README1
-rw-r--r--action.cpp56
-rw-r--r--apppbx.cpp33
-rw-r--r--apppbx.h3
-rw-r--r--dss1.cpp31
-rw-r--r--mISDN.cpp8
-rw-r--r--message.h1
-rw-r--r--route.c6
-rw-r--r--route.h19
-rw-r--r--socket_server.c6
10 files changed, 111 insertions, 53 deletions
diff --git a/README b/README
index 2515150..bc747c2 100644
--- a/README
+++ b/README
@@ -534,6 +534,7 @@ Changes after Version 1.7
- Added new option to interface.conf: "nonotify" to disable notify messages.
- Replaced polling main loop by event driven "select()" loop.
- Also replaced polling main loop by event driven "select()" loop on chan_lcr.
+- Added "release" action and timeout to "execute" action.
diff --git a/action.cpp b/action.cpp
index bf7c23d..aa83304 100644
--- a/action.cpp
+++ b/action.cpp
@@ -135,7 +135,7 @@ void EndpointAppPBX::action_dialing_internal(void)
trace_header("ACTION extension (extension doesn't exist)", DIRECTION_NONE);
add_trace("extension", NULL, dialinginfo.id);
end_trace();
- release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0, 0);
+ release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0, 0, 0);
new_state(EPOINT_STATE_OUT_DISCONNECT);
message_disconnect_port(portlist, CAUSE_UNALLOCATED, LOCATION_PRIVATE_LOCAL, "");
set_tone(portlist, "cause_86");
@@ -147,7 +147,7 @@ void EndpointAppPBX::action_dialing_internal(void)
add_trace("extension", NULL, dialinginfo.id);
end_trace();
new_state(EPOINT_STATE_OUT_DISCONNECT);
- release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0, 0);
+ release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0, 0, 0);
message_disconnect_port(portlist, CAUSE_REJECTED, LOCATION_PRIVATE_LOCAL, "");
set_tone(portlist, "cause_81");
return;
@@ -273,7 +273,7 @@ void EndpointAppPBX::action_dialing_external(void)
if (e_ext.rights < 2) {
trace_header("ACTION extern (calling denied)", DIRECTION_NONE);
end_trace();
- release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_REJECTED, 0, 0);
+ release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_REJECTED, 0, 0, 0);
set_tone(portlist, "cause_82");
denied:
message_disconnect_port(portlist, CAUSE_REJECTED, LOCATION_PRIVATE_LOCAL, "");
@@ -288,7 +288,7 @@ void EndpointAppPBX::action_dialing_external(void)
if (e_ext.rights < 3) {
trace_header("ACTION extern (national calls denied)", DIRECTION_NONE);
end_trace();
- release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_REJECTED, 0, 0);
+ release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_REJECTED, 0, 0, 0);
set_tone(portlist, "cause_83");
goto denied;
}
@@ -300,7 +300,7 @@ void EndpointAppPBX::action_dialing_external(void)
if (e_ext.rights < 4) {
trace_header("ACTION extern (international calls denied)", DIRECTION_NONE);
end_trace();
- release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_REJECTED, 0, 0);
+ release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_REJECTED, 0, 0, 0);
set_tone(portlist, "cause_84");
goto denied;
}
@@ -1781,6 +1781,48 @@ void EndpointAppPBX::action_dialing_disconnect(void)
/*
+ * process dialing release
+ */
+void EndpointAppPBX::action_dialing_release(void)
+{
+ struct route_param *rparam;
+ int cause = CAUSE_NORMAL; /* normal call clearing */
+ int location = LOCATION_PRIVATE_LOCAL;
+ char cause_string[256] = "", display[84] = "";
+
+ /* check cause parameter */
+ if ((rparam = routeparam(e_action, PARAM_CAUSE))) {
+ cause = rparam->integer_value;
+ PDEBUG(DEBUG_EPOINT, "EPOINT(%d): 'cause' is given: %d\n", ea_endpoint->ep_serial, cause);
+ }
+ if ((rparam = routeparam(e_action, PARAM_LOCATION))) {
+ location = rparam->integer_value;
+ PDEBUG(DEBUG_EPOINT, "EPOINT(%d): 'location' is given: %d\n", ea_endpoint->ep_serial, location);
+ }
+
+
+ /* use cause as sample, if not given later */
+ SPRINT(cause_string, "cause_%02x", cause);
+
+ /* check display */
+ if ((rparam = routeparam(e_action, PARAM_DISPLAY))) {
+ SCPY(display, rparam->string_value);
+ PDEBUG(DEBUG_EPOINT, "EPOINT(%d): 'display' is given: %s\n", ea_endpoint->ep_serial, display);
+ }
+
+ /* disconnect only if connect parameter is not given */
+ trace_header("ACTION release", DIRECTION_NONE);
+ add_trace("cause", "value", "%d", cause);
+ add_trace("cause", "location", "%d", location);
+ if (display[0])
+ add_trace("display", NULL, "%s", display);
+ end_trace();
+ e_action = NULL;
+ release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, location, cause, 1);
+ return;
+}
+
+/*
* process dialing help
*/
void EndpointAppPBX::action_dialing_help(void)
@@ -2148,10 +2190,10 @@ void EndpointAppPBX::process_dialing(int timeout)
if (e_action->index == ACTION_DISCONNECT
|| e_state == EPOINT_STATE_OUT_DISCONNECT) {
/* release after disconnect */
- release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL);
+ release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
goto end;
}
- release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0, 0);
+ release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0, 0, 0);
e_action = e_action->next;
if (!e_action) {
/* nothing more, so we release */
diff --git a/apppbx.cpp b/apppbx.cpp
index 46b1f62..f630dbf 100644
--- a/apppbx.cpp
+++ b/apppbx.cpp
@@ -201,7 +201,7 @@ void EndpointAppPBX::new_state(int state)
/* release join and port (as specified)
*/
-void EndpointAppPBX::release(int release, int joinlocation, int joincause, int portlocation, int portcause)
+void EndpointAppPBX::release(int release, int joinlocation, int joincause, int portlocation, int portcause, int force)
{
struct port_list *portlist;
struct lcr_msg *message;
@@ -238,6 +238,7 @@ void EndpointAppPBX::release(int release, int joinlocation, int joincause, int p
message = message_create(ea_endpoint->ep_serial, portlist->port_id, EPOINT_TO_PORT, MESSAGE_RELEASE);
message->param.disconnectinfo.cause = portcause;
message->param.disconnectinfo.location = portlocation;
+ message->param.disconnectinfo.force = force; // set, if port should release imediately
message_put(message);
logmessage(message->type, &message->param, portlist->port_id, DIRECTION_OUT);
}
@@ -879,7 +880,7 @@ void EndpointAppPBX::out_setup(void)
}
if (atemp) {
PERROR("EPOINT(%d) noknocking and currently a call\n", ea_endpoint->ep_serial);
- release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_BUSY, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYSPE_ join, port */
+ release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_BUSY, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0); /* RELEASE_TYSPE_ join, port */
return; /* must exit here */
}
}
@@ -892,7 +893,7 @@ void EndpointAppPBX::out_setup(void)
// if (!read_extension(&e_ext, exten))
if (!read_extension(&e_ext, e_dialinginfo.id)) {
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) extension %s not configured\n", ea_endpoint->ep_serial, e_dialinginfo.id);
- release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_OUTOFORDER, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, join, port */
+ release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_OUTOFORDER, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0); /* RELEASE_TYPE, join, port */
return; /* must exit here */
}
@@ -1156,7 +1157,7 @@ void EndpointAppPBX::out_setup(void)
end_trace();
if (!ea_endpoint->ep_join_id)
break;
- release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, cause, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, join, port */
+ release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, cause, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0); /* RELEASE_TYPE, join, port */
return; /* must exit here */
}
break;
@@ -1245,7 +1246,7 @@ void EndpointAppPBX::out_setup(void)
end_trace();
if (!ea_endpoint->ep_join_id)
break;
- release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NOCHANNEL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, join, port */
+ release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NOCHANNEL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0); /* RELEASE_TYPE, join, port */
return; /* must exit here */
}
break;
@@ -1424,7 +1425,7 @@ void EndpointAppPBX::hookflash(void)
port->set_echotest(0);
}
if (ea_endpoint->ep_join_id) {
- release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, join, port */
+ release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0); /* RELEASE_TYPE, join, port */
}
e_ruleset = ruleset_main;
if (e_ruleset)
@@ -2237,7 +2238,7 @@ void EndpointAppPBX::port_disconnect_release(struct port_list *portlist, int mes
}
if (message_type == MESSAGE_RELEASE)
ea_endpoint->free_portlist(portlist);
- release(RELEASE_ALL, location, cause, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, callcause, portcause */
+ release(RELEASE_ALL, location, cause, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0); /* RELEASE_TYPE, callcause, portcause */
return; /* must exit here */
}
@@ -2254,7 +2255,7 @@ void EndpointAppPBX::port_timeout(struct port_list *portlist, int message_type,
add_trace("state", NULL, "outgoing setup/dialing");
end_trace();
/* no user responding */
- release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NOUSER, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL);
+ release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NOUSER, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
return; /* must exit here */
case PORT_STATE_IN_SETUP:
@@ -2269,7 +2270,7 @@ void EndpointAppPBX::port_timeout(struct port_list *portlist, int message_type,
end_trace();
param->disconnectinfo.cause = CAUSE_NOUSER; /* no user responding */
param->disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
- release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NOUSER, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL);
+ release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NOUSER, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
return; /* must exit here */
case PORT_STATE_IN_PROCEEDING:
@@ -2283,7 +2284,7 @@ void EndpointAppPBX::port_timeout(struct port_list *portlist, int message_type,
end_trace();
param->disconnectinfo.cause = CAUSE_NOANSWER; /* no answer */
param->disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
- release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NOANSWER, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL);
+ release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NOANSWER, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
return; /* must exit here */
case PORT_STATE_CONNECT:
@@ -2291,7 +2292,7 @@ void EndpointAppPBX::port_timeout(struct port_list *portlist, int message_type,
end_trace();
param->disconnectinfo.cause = CAUSE_NORMAL; /* normal */
param->disconnectinfo.location = LOCATION_PRIVATE_LOCAL;
- release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL);
+ release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
return; /* must exit here */
case PORT_STATE_IN_ALERTING:
@@ -2305,7 +2306,7 @@ void EndpointAppPBX::port_timeout(struct port_list *portlist, int message_type,
add_trace("state", NULL, "disconnect");
end_trace();
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) in this special case, we release due to disconnect timeout.\n", ea_endpoint->ep_serial);
- release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL);
+ release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
return; /* must exit here */
default:
@@ -2323,7 +2324,7 @@ void EndpointAppPBX::port_timeout(struct port_list *portlist, int message_type,
message_disconnect_port(portlist, param->disconnectinfo.cause, param->disconnectinfo.location, "");
portlist = portlist->next;
}
- release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, join, port */
+ release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0); /* RELEASE_TYPE, join, port */
}
/* port MESSAGE_NOTIFY */
@@ -2919,7 +2920,7 @@ void EndpointAppPBX::join_disconnect_release(int message_type, union parameter *
/* we are powerdialing, if e_powerdial_on is set and limit is not exceeded if given */
if (e_powerdial_on && ((e_powercount+1)<e_powerlimit || e_powerlimit<1)) {
- release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, join, port */
+ release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL,0 ); /* RELEASE_TYPE, join, port */
/* set time for power dialing */
schedule_timer(&e_powerdial_timeout, (int)e_powerdelay, 0); /* set redial in the future */
@@ -2970,7 +2971,7 @@ void EndpointAppPBX::join_disconnect_release(int message_type, union parameter *
&& e_state!=EPOINT_STATE_IN_ALERTING)
|| !ea_endpoint->ep_portlist) { /* or no port */
process_hangup(param->disconnectinfo.cause, param->disconnectinfo.location);
- release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, param->disconnectinfo.cause); /* RELEASE_TYPE, join, port */
+ release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, param->disconnectinfo.cause, 0); /* RELEASE_TYPE, join, port */
return; /* must exit here */
}
/* save cause */
@@ -2992,7 +2993,7 @@ void EndpointAppPBX::join_disconnect_release(int message_type, union parameter *
|| !e_join_pattern) { /* no patterns */
PDEBUG(DEBUG_EPOINT, "EPOINT(%d) we have own cause or we have no patterns. (own_cause=%d pattern=%d)\n", ea_endpoint->ep_serial, e_ext.own_cause, e_join_pattern);
if (message_type != MESSAGE_RELEASE)
- release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL); /* RELEASE_TYPE, join, port */
+ release(RELEASE_JOIN, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0); /* RELEASE_TYPE, join, port */
e_join_pattern = 0;
} else { /* else we enable audio */
message = message_create(ea_endpoint->ep_serial, ea_endpoint->ep_join_id, EPOINT_TO_JOIN, MESSAGE_AUDIOPATH);
diff --git a/apppbx.h b/apppbx.h
index b10a119..8d2cb07 100644
--- a/apppbx.h
+++ b/apppbx.h
@@ -224,7 +224,7 @@ class EndpointAppPBX : public EndpointApp
/* epoint */
void new_state(int state);
- void release(int release, int joinlocation, int joincause, int portlocation, int portcause);
+ void release(int release, int joinlocation, int joincause, int portlocation, int portcause, int force);
void notify_active(void);
void keypad_function(char digit);
void set_tone(struct port_list *portlist, const char *tone);
@@ -288,6 +288,7 @@ class EndpointAppPBX : public EndpointApp
void action_dialing_goto(void);
void action_dialing_menu(void);
void action_dialing_disconnect(void);
+ void action_dialing_release(void);
void action_dialing_help(void);
void action_dialing_deflect(void);
void action_dialing_setforward(void);
diff --git a/dss1.cpp b/dss1.cpp
index 4a96e28..3bcf410 100644
--- a/dss1.cpp
+++ b/dss1.cpp
@@ -2607,45 +2607,46 @@ void Pdss1::message_release(unsigned int epoint_id, int message_id, union parame
char *p = NULL;
/*
- * we may only release during incoming disconnect state.
- * this means that the endpoint doesnt require audio anymore
+ * if we are on incoming call setup, we may reject by sending a release_complete
+ * also on outgoing call setup, we send a release complete, BUT this is not conform. (i don't know any other way)
*/
- if (p_state == PORT_STATE_IN_DISCONNECT
- || p_state == PORT_STATE_OUT_DISCONNECT) {
- /* sending release */
+ if (p_state==PORT_STATE_IN_SETUP
+ || p_state==PORT_STATE_OUT_SETUP) {
+//#warning remove me
+//PDEBUG(DEBUG_LOG, "JOLLY sending release complete %d\n", p_serial);
+ /* sending release complete */
l3m = create_l3msg();
l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_REQ, DIRECTION_OUT);
/* send cause */
enc_ie_cause(l3m, (p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
end_trace();
- p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE, p_m_d_l3id, l3m);
+ p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE_COMPLETE, p_m_d_l3id, l3m);
new_state(PORT_STATE_RELEASE);
/* remove epoint */
free_epointid(epoint_id);
// wait for callref to be released
return;
-
}
/*
- * if we are on incoming call setup, we may reject by sending a release_complete
- * also on outgoing call setup, we send a release complete, BUT this is not conform. (i don't know any other way)
+ * we may only release during incoming disconnect state.
+ * this means that the endpoint doesnt require audio anymore
*/
- if (p_state==PORT_STATE_IN_SETUP
- || p_state==PORT_STATE_OUT_SETUP) {
-//#warning remove me
-//PDEBUG(DEBUG_LOG, "JOLLY sending release complete %d\n", p_serial);
- /* sending release complete */
+ if (p_state == PORT_STATE_IN_DISCONNECT
+ || p_state == PORT_STATE_OUT_DISCONNECT
+ || param->disconnectinfo.force) {
+ /* sending release */
l3m = create_l3msg();
l1l2l3_trace_header(p_m_mISDNport, this, L3_RELEASE_REQ, DIRECTION_OUT);
/* send cause */
enc_ie_cause(l3m, (p_m_mISDNport->locally && param->disconnectinfo.location==LOCATION_PRIVATE_LOCAL)?LOCATION_PRIVATE_LOCAL:param->disconnectinfo.location, param->disconnectinfo.cause);
end_trace();
- p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE_COMPLETE, p_m_d_l3id, l3m);
+ p_m_mISDNport->ml3->to_layer3(p_m_mISDNport->ml3, MT_RELEASE, p_m_d_l3id, l3m);
new_state(PORT_STATE_RELEASE);
/* remove epoint */
free_epointid(epoint_id);
// wait for callref to be released
return;
+
}
#if 0
diff --git a/mISDN.cpp b/mISDN.cpp
index 3e7751e..035b78b 100644
--- a/mISDN.cpp
+++ b/mISDN.cpp
@@ -1834,8 +1834,11 @@ static int mISDN_upqueue(struct lcr_fd *fd, unsigned int what, void *instance, i
char byte;
/* unset global semaphore */
- read(fd->fd, &byte, 1);
upqueue_avail = 0;
+ // with a very small incident, upqueue_avail may be set by mISDN thread and
+ // another byte may be sent to the pipe, which causes a call to this function
+ // again with nothing in the upqueue. this is no problem.
+ read(fd->fd, &byte, 1);
/* process all ports */
mISDNport = mISDNport_first;
@@ -2060,6 +2063,9 @@ int do_layer3(struct mlayer3 *ml3, unsigned int cmd, unsigned int pid, struct l3
l3m->pid = pid;
mqueue_tail(&mISDNport->upqueue, mb);
if (!upqueue_avail) {
+ // multiple threads may cause multiple calls of this section, but this
+ // results only in multiple processing of the upqueue read.
+ // this is no problem.
upqueue_avail = 1;
char byte = 0;
write(upqueue_pipe[1], &byte, 1);
diff --git a/message.h b/message.h
index a7f15b7..3c775cc 100644
--- a/message.h
+++ b/message.h
@@ -199,6 +199,7 @@ struct disconnect_info {
int cause; /* reason for disconnect */
int location; /* disconnect location */
char display[84]; /* optional display information */
+ int force; /* special flag to release imediately */
};
/* call-info structure REDIR */
diff --git a/route.c b/route.c
index a448f39..959b584 100644
--- a/route.c
+++ b/route.c
@@ -342,6 +342,10 @@ struct action_defs action_defs[] = {
"disconnect", NULL, &EndpointAppPBX::action_dialing_disconnect, NULL,
PARAM_CONNECT | PARAM_CAUSE | PARAM_LOCATION | PARAM_SAMPLE | PARAM_DISPLAY,
"Caller gets disconnected optionally with given cause and given sample and given display text."},
+ { ACTION_RELEASE,
+ "release", NULL, &EndpointAppPBX::action_dialing_release, NULL,
+ PARAM_CONNECT | PARAM_CAUSE | PARAM_LOCATION | PARAM_DISPLAY,
+ "Same as 'disconnect', but using RELEASE message on ISDN."},
{ ACTION_DEFLECT,
"deflect", NULL, &EndpointAppPBX::action_dialing_deflect, NULL,
PARAM_DEST,
@@ -354,7 +358,7 @@ struct action_defs action_defs[] = {
// "The call forward is set within the telephone network of the external line."},
{ ACTION_EXECUTE,
"execute", &EndpointAppPBX::action_init_execute, NULL, &EndpointAppPBX::action_hangup_execute,
- PARAM_CONNECT | PARAM_EXECUTE | PARAM_PARAM | PARAM_ON,
+ PARAM_CONNECT | PARAM_EXECUTE | PARAM_PARAM | PARAM_ON | PARAM_TIMEOUT,
"Executes the given script file. The file must terminate quickly, because it will halt the PBX."},
{ ACTION_FILE,
"file", NULL, NULL, &EndpointAppPBX::action_hangup_file,
diff --git a/route.h b/route.h
index 3530ef4..dca5a4e 100644
--- a/route.h
+++ b/route.h
@@ -174,15 +174,16 @@ enum { /* defines when a statement should be executed */
#define ACTION_GOTO 20
#define ACTION_MENU 21
#define ACTION_DISCONNECT 22
-#define ACTION_DEFLECT 23
-#define ACTION_SETFORWARD 24
-#define ACTION_EXECUTE 25
-#define ACTION_FILE 26
-#define ACTION_PICK 27
-#define ACTION_PASSWORD 28
-#define ACTION_PASSWORD_WRITE 29
-#define ACTION_NOTHING 30
-#define ACTION_EFI 31
+#define ACTION_RELEASE 23
+#define ACTION_DEFLECT 24
+#define ACTION_SETFORWARD 25
+#define ACTION_EXECUTE 26
+#define ACTION_FILE 27
+#define ACTION_PICK 28
+#define ACTION_PASSWORD 29
+#define ACTION_PASSWORD_WRITE 30
+#define ACTION_NOTHING 31
+#define ACTION_EFI 32
struct route_cond { /* an item */
struct route_cond *next; /* next entry */
diff --git a/socket_server.c b/socket_server.c
index b67b91f..3083085 100644
--- a/socket_server.c
+++ b/socket_server.c
@@ -278,7 +278,7 @@ int admin_route(struct admin_queue **responsep)
release:
unsched_timer(&apppbx->e_callback_timeout);
apppbx->e_action = NULL;
- apppbx->release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL);
+ apppbx->release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
start_trace(-1,
NULL,
numberrize_callerinfo(apppbx->e_callerinfo.id, apppbx->e_callerinfo.ntype, options.national, options.international),
@@ -488,7 +488,7 @@ int admin_release(struct admin_queue **responsep, char *message)
}
unsched_timer(&apppbx->e_callback_timeout);
- apppbx->release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL);
+ apppbx->release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
out:
/* attach to response chain */
@@ -1123,7 +1123,7 @@ int admin_handle_con(struct lcr_fd *fd, unsigned int what, void *instance, int i
epoint = find_epoint_id(admin->epointid);
if (epoint) {
((class DEFAULT_ENDPOINT_APP *)epoint->ep_app)->
- release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL);
+ release(RELEASE_ALL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, LOCATION_PRIVATE_LOCAL, CAUSE_NORMAL, 0);
}
}