[asterisk-commits] nadi: branch group/trunk-cm-csel-hash r47722 - in
/team/group/trunk-cm-csel-h...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Thu Nov 16 04:43:20 MST 2006
Author: nadi
Date: Thu Nov 16 05:43:19 2006
New Revision: 47722
URL: http://svn.digium.com/view/asterisk?view=rev&rev=47722
Log:
extended the transition table
Modified:
team/group/trunk-cm-csel-hash/channels/chan_misdn.c
team/group/trunk-cm-csel-hash/channels/misdn/isdn_lib.c
Modified: team/group/trunk-cm-csel-hash/channels/chan_misdn.c
URL: http://svn.digium.com/view/asterisk/team/group/trunk-cm-csel-hash/channels/chan_misdn.c?view=diff&rev=47722&r1=47721&r2=47722
==============================================================================
--- team/group/trunk-cm-csel-hash/channels/chan_misdn.c (original)
+++ team/group/trunk-cm-csel-hash/channels/chan_misdn.c Thu Nov 16 05:43:19 2006
@@ -210,6 +210,8 @@
int other_pid;
struct chan_list *other_ch;
const struct tone_zone_sound *ts;
+
+ int destroy_me;
struct chan_list *next;
};
@@ -688,6 +690,11 @@
static struct statemachine_handle_retval handle_mevent_release_complete (void *p, int state, int event);
static struct statemachine_handle_retval handle_mevent_cleanup (void *p, int state, int event);
static struct statemachine_handle_retval handle_mevent_facility (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_retrieve (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_restart (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_hold (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_timeout_1 (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_timeout_2 (void *p, int state, int event);
static struct statemachine_transition misdn_state_table[] = {
/*
@@ -726,6 +733,28 @@
{ STATE_ANY, EVENT_CONNECT, STATE_CONTINUE, EVENT_CONNECT_ACKNOWLEDGE, handle_mevent_connect },
{ STATE_ANY, EVENT_CONNECT, MISDN_CONNECTED, AEVENT_CANSWER, NULL },
{ STATE_ANY, EVENT_DISCONNECT, MISDN_DISCONNECTED, EVENT_NONE, handle_mevent_disconnect },
+ { STATE_ANY, EVENT_RETRIEVE, MISDN_CONNECTED, EVENT_RETRIEVE_ACKNOWLEDGE, handle_mevent_retrieve },
+ { STATE_ANY, EVENT_HOLD, MISDN_HOLDED, EVENT_HOLD_ACKNOWLEDGE, handle_mevent_hold },
+
+ { MISDN_DIALING, EVENT_TIMEOUT, STATE_KEEP, EVENT_DISCONNECT, handle_mevent_timeout_1 },
+ { MISDN_PROGRESS, EVENT_TIMEOUT, STATE_KEEP, EVENT_DISCONNECT, handle_mevent_timeout_1 },
+ { MISDN_CALLING, EVENT_TIMEOUT, STATE_KEEP, EVENT_DISCONNECT, handle_mevent_timeout_1 },
+ { MISDN_ALERTING, EVENT_TIMEOUT, STATE_KEEP, EVENT_DISCONNECT, handle_mevent_timeout_1 },
+ { MISDN_PROCEEDING, EVENT_TIMEOUT, STATE_KEEP, EVENT_DISCONNECT, handle_mevent_timeout_1 },
+ { MISDN_CALLING_ACKNOWLEDGE, EVENT_TIMEOUT, STATE_KEEP, EVENT_DISCONNECT, handle_mevent_timeout_1 },
+ { MISDN_WAITING4DIGS, EVENT_TIMEOUT, STATE_KEEP, EVENT_DISCONNECT, handle_mevent_timeout_2 },
+ { MISDN_CLEANING, EVENT_TIMEOUT, STATE_KEEP, EVENT_NONE, NULL },
+ { STATE_ANY, EVENT_TIMEOUT, STATE_KEEP, EVENT_RELEASE_COMPLETE, NULL },
+
+ { MISDN_DIALING, EVENT_BCHAN_ERROR, STATE_KEEP, EVENT_DISCONNECT, handle_mevent_timeout_1 },
+ { MISDN_PROGRESS, EVENT_BCHAN_ERROR, STATE_KEEP, EVENT_DISCONNECT, handle_mevent_timeout_1 },
+ { MISDN_CALLING, EVENT_BCHAN_ERROR, STATE_KEEP, EVENT_DISCONNECT, handle_mevent_timeout_1 },
+ { MISDN_ALERTING, EVENT_BCHAN_ERROR, STATE_KEEP, EVENT_DISCONNECT, handle_mevent_timeout_1 },
+ { MISDN_PROCEEDING, EVENT_BCHAN_ERROR, STATE_KEEP, EVENT_DISCONNECT, handle_mevent_timeout_1 },
+ { MISDN_CALLING_ACKNOWLEDGE, EVENT_BCHAN_ERROR, STATE_KEEP, EVENT_DISCONNECT, handle_mevent_timeout_1 },
+ { MISDN_WAITING4DIGS, EVENT_BCHAN_ERROR, STATE_KEEP, EVENT_DISCONNECT, handle_mevent_timeout_2 },
+ { MISDN_CLEANING, EVENT_BCHAN_ERROR, STATE_KEEP, EVENT_NONE, NULL },
+ { STATE_ANY, EVENT_BCHAN_ERROR, STATE_KEEP, EVENT_RELEASE_COMPLETE, NULL },
/* state keeping events */
{ STATE_ANY, EVENT_PORT_ALARM, STATE_KEEP, EVENT_NONE, handle_mevent_port_alarm },
@@ -735,6 +764,7 @@
{ STATE_ANY, EVENT_RELEASE, STATE_KEEP, EVENT_RELEASE_COMPLETE, handle_mevent_release },
{ STATE_ANY, EVENT_CLEANUP, STATE_KEEP, EVENT_NONE, handle_mevent_cleanup },
{ STATE_ANY, EVENT_FACILITY, STATE_KEEP, EVENT_NONE, handle_mevent_facility },
+ { STATE_ANY, EVENT_RESTART, STATE_KEEP, EVENT_NONE, handle_mevent_restart },
/* noop events */
{ STATE_ANY, EVENT_BCHAN_ACTIVATED, STATE_KEEP, EVENT_NONE, NULL},
@@ -857,8 +887,11 @@
int first = 0;
char tmpbuf[256];
+ if (!num)
+ return;
+
#define IF_INFO(i,fmt,parm) \
- if (*elems & (i) && num) { \
+ if (*elems & (i)) { \
*elems &= ~(i); \
snprintf(tmpbuf, sizeof(tmpbuf), "%s" fmt, !(first--) ? "" : " ", parm); \
strncat(buf, tmpbuf, bufsize); \
@@ -916,10 +949,17 @@
static int send_event (void *p, int event)
{
struct chan_list *ch = p;
+ struct misdn_bchannel *bc = ch->bc;
int re = 0;
if (event > EVENT_NOTHING && event < EVENT_UNKNOWN) {
- misdn_lib_send_event(ch->bc, event);
+ misdn_lib_send_event(bc, event);
+ if (event == EVENT_HOLD_ACKNOWLEDGE) {
+ /*forget the channel now*/
+ ch->bc = NULL;
+ ch->hold_info.port = bc->port;
+ ch->hold_info.channel = bc->channel;
+ }
} else {
switch (event) {
case AEVENT_CPROCEEDING:
@@ -1788,13 +1828,13 @@
}
/* Isdn asks us to release channel, pendant to misdn_hangup */
-static void release_chan (struct misdn_bchannel *bc)
+static void release_chan (struct chan_list *ch)
{
struct ast_channel *ast;
- struct chan_list *ch = find_chan_by_bc(cl_te, bc);
+ struct misdn_bchannel *bc = ch->bc;
if (!ch) {
- chan_misdn_log(2, bc->port, "release_chan: Ch not found!\n");
+ chan_misdn_log(2, bc->port, "release_chan: No ch!\n");
return;
}
ast = ch->ast;
@@ -3835,6 +3875,7 @@
ch->bc->out_cause = 16;
hangup_chan(ch);
+ ch->destroy_me = 1;
return ch->bc->need_release_complete ? RE_DEFAULT : RE_NONE;
}
@@ -3845,6 +3886,7 @@
stop_bc_tones(ch);
hangup_chan(ch);
+ ch->destroy_me = 1;
return RE_DEFAULT;
}
@@ -3857,6 +3899,7 @@
if (state == MISDN_CALLING)
ch->bc->cause = 27; /* Destination out of order */
hangup_chan(ch);
+ ch->destroy_me = 1;
return RE_DEFAULT;
}
@@ -3895,6 +3938,89 @@
return RE_DEFAULT;
}
+static struct statemachine_handle_retval handle_mevent_retrieve (void *p, int state, int event)
+{
+ struct chan_list *ch = p;
+ struct ast_channel *hold_ast;
+
+ hold_ast = AST_BRIDGED_P(ch->ast);
+ if (hold_ast)
+ ast_moh_stop(hold_ast);
+
+ return RE_DEFAULT;
+}
+
+static struct statemachine_handle_retval handle_mevent_restart (void *p, int state, int event)
+{
+ struct chan_list *ch = p;
+
+ stop_bc_tones(ch);
+ ch->destroy_me = 1;
+
+ return RE_DEFAULT;
+}
+
+static struct statemachine_handle_retval handle_mevent_hold (void *p, int state, int event)
+{
+ struct chan_list *ch = p;
+ struct misdn_bchannel *bc = ch->bc;
+ struct ast_channel *bridged;
+ int hold_allowed = 0;
+
+ cm_get_int(misdn_cm, hold_allowed, PORT, MCFG_HOLDALLOWED, bc->port);
+ if (!hold_allowed) {
+ chan_misdn_log(-1, bc->port, "Hold not allowed for this port.\n");
+ return RE_STATE_EVENT(STATE_KEEP, EVENT_HOLD_REJECT);
+ }
+
+ bridged = AST_BRIDGED_P(ch->ast);
+ if (bridged) {
+ chan_misdn_log(2, bc->port, "Bridge partner is of type: %s\n", bridged->tech->type);
+ ch->l3id = bc->l3_id;
+
+ /* XXX This should queue an AST_CONTROL_HOLD frame on this channel
+ * instead of starting moh on the bridged channel directly */
+ ast_moh_start(bridged, NULL, NULL);
+ return RE_DEFAULT;
+ } else {
+ chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n");
+ return RE_STATE_EVENT(STATE_KEEP, EVENT_HOLD_REJECT);
+ }
+}
+
+static struct statemachine_handle_retval handle_mevent_timeout_1 (void *p, int state, int event)
+{
+ struct chan_list *ch = p;
+ struct misdn_bchannel *bc = ch->bc;
+
+ if ((state == MISDN_DIALING || state == MISDN_PROGRESS) && bc->nt && !ch->nttimeout)
+ return RE_NONE;
+
+ if (bc->nt) {
+ bc->progress_indicator = 8;
+ hanguptone_indicate(ch);
+ }
+ bc->out_cause = 1;
+
+ return RE_DEFAULT;
+}
+
+static struct statemachine_handle_retval handle_mevent_timeout_2 (void *p, int state, int event)
+{
+ struct chan_list *ch = p;
+ struct misdn_bchannel *bc = ch->bc;
+
+ if (bc->nt) {
+ bc->progress_indicator = 8;
+ bc->out_cause = 1;
+ hanguptone_indicate(ch);
+ return RE_DEFAULT;
+ } else {
+ bc->out_cause = 16;
+ return RE_EVENT(EVENT_RELEASE);
+ }
+}
+
/* The big event handler for all events from mISDN (isdn_lib) */
static enum event_response_e cb_events (enum event_e event, struct misdn_bchannel *bc, void *user_data)
{
@@ -3930,9 +4056,17 @@
}
} else {
switch (event) {
+ case EVENT_RETRIEVE:
+ ch = find_holded_l3(cl_te, bc->l3_id, 1);
+ if (!ch) {
+ ast_log(LOG_WARNING, "Found no holded channel, cannot retrieve\n");
+ misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
+ return RESPONSE_OK;
+ }
+ ch->bc = bc;
+ break;
case EVENT_SETUP:
case EVENT_PORT_ALARM:
- case EVENT_RETRIEVE:
case EVENT_NEW_BC:
case EVENT_FACILITY:
break;
@@ -4087,118 +4221,15 @@
* run the statemachine and return if the event could be handled
*/
if (ch && !statemachine_run(ch->sm, event)) {
- if (event == EVENT_RELEASE || event == EVENT_RELEASE_COMPLETE || event == EVENT_CLEANUP)
- release_chan(ch->bc);
+ if (ch->destroy_me)
+ release_chan(ch);
return RESPONSE_OK;
}
/*
* this is for events not (yet) handled by our statemachine
*/
- switch (event) {
- case EVENT_BCHAN_ERROR:
- case EVENT_TIMEOUT:
- if (ch && bc)
- chan_misdn_log(2, bc->port, "--> state: %s\n", get_state_string(statemachine_get_state(ch->sm)));
- switch (statemachine_get_state(ch->sm)) {
- case MISDN_DIALING:
- case MISDN_PROGRESS:
- if (bc->nt && !ch->nttimeout)
- break;
- case MISDN_CALLING:
- case MISDN_ALERTING:
- case MISDN_PROCEEDING:
- case MISDN_CALLING_ACKNOWLEDGE:
- if (bc->nt) {
- bc->progress_indicator = 8;
- hanguptone_indicate(ch);
- }
- bc->out_cause = 1;
- misdn_lib_send_event(bc, EVENT_DISCONNECT);
- break;
- case MISDN_WAITING4DIGS:
- if (bc->nt) {
- bc->progress_indicator = 8;
- bc->out_cause = 1;
- hanguptone_indicate(ch);
- misdn_lib_send_event(bc, EVENT_DISCONNECT);
- } else {
- bc->out_cause = 16;
- misdn_lib_send_event(bc, EVENT_RELEASE);
- }
- break;
- case MISDN_CLEANING:
- chan_misdn_log(2, bc->port, " --> in state cleaning .. so ingoring, the stack should clean it for us\n");
- break;
- default:
- misdn_lib_send_event(bc, EVENT_RELEASE_COMPLETE);
- }
- break;
-
- /***************************/
- /** Supplementary Services **/
- /***************************/
- case EVENT_RETRIEVE:
- {
- struct ast_channel *hold_ast;
-
- ch = find_holded_l3(cl_te, bc->l3_id, 1);
- if (!ch) {
- ast_log(LOG_WARNING, "Found no Holded channel, cannot Retrieve\n");
- misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
- break;
- }
-
- /*remember the channel again*/
- ch->bc = bc;
- statemachine_set_state(ch->sm, MISDN_CONNECTED);
-
- hold_ast = AST_BRIDGED_P(ch->ast);
- if (hold_ast)
- ast_moh_stop(hold_ast);
- if (misdn_lib_send_event(bc, EVENT_RETRIEVE_ACKNOWLEDGE) < 0)
- misdn_lib_send_event(bc, EVENT_RETRIEVE_REJECT);
- }
- break;
- case EVENT_HOLD:
- {
- int hold_allowed = 0;
- struct ast_channel *bridged;
-
- cm_get_int(misdn_cm, hold_allowed, PORT, MCFG_HOLDALLOWED, bc->port);
- if (!hold_allowed) {
- chan_misdn_log(-1, bc->port, "Hold not allowed this port.\n");
- misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
- break;
- }
- bridged = AST_BRIDGED_P(ch->ast);
- if (bridged){
- chan_misdn_log(2, bc->port, "Bridge Partner is of type: %s\n", bridged->tech->type);
- statemachine_set_state(ch->sm, MISDN_HOLDED);
- ch->l3id = bc->l3_id;
- misdn_lib_send_event(bc, EVENT_HOLD_ACKNOWLEDGE);
- /* XXX This should queue an AST_CONTROL_HOLD frame on this channel
- * instead of starting moh on the bridged channel directly */
- ast_moh_start(bridged, NULL, NULL);
-
- /*forget the channel now*/
- ch->bc = NULL;
- ch->hold_info.port = bc->port;
- ch->hold_info.channel = bc->channel;
- } else {
- misdn_lib_send_event(bc, EVENT_HOLD_REJECT);
- chan_misdn_log(0, bc->port, "We aren't bridged to anybody\n");
- }
- }
- break;
- case EVENT_RESTART:
- stop_bc_tones(ch);
- release_chan(bc);
- break;
- default:
- ast_log(LOG_NOTICE, "Got Unknown Event\n");
- break;
- }
+ ast_log(LOG_NOTICE, "Got Unknown Event\n");
return RESPONSE_OK;
}
Modified: team/group/trunk-cm-csel-hash/channels/misdn/isdn_lib.c
URL: http://svn.digium.com/view/asterisk/team/group/trunk-cm-csel-hash/channels/misdn/isdn_lib.c?view=diff&rev=47722&r1=47721&r2=47722
==============================================================================
--- team/group/trunk-cm-csel-hash/channels/misdn/isdn_lib.c (original)
+++ team/group/trunk-cm-csel-hash/channels/misdn/isdn_lib.c Thu Nov 16 05:43:19 2006
@@ -3213,9 +3213,8 @@
if (bc->channel <=0 ) { /* else we have the channel already */
if (!find_free_chan_in_stack(stack, bc, 0)) {
cb_log(0, stack->port, " No free channel at the moment\n");
-
- err=-ENOCHAN;
- goto ERR;
+ event = EVENT_RETRIEVE_REJECT;
+ break;
}
}
/* Its that i generate channels */
More information about the asterisk-commits
mailing list