[asterisk-commits] nadi: branch group/trunk-cm-csel-hash r47429 -
/team/group/trunk-cm-csel-hash...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Fri Nov 10 08:53:35 MST 2006
Author: nadi
Date: Fri Nov 10 09:53:34 2006
New Revision: 47429
URL: http://svn.digium.com/view/asterisk?view=rev&rev=47429
Log:
state machine handler function returns a touple of state and event
Modified:
team/group/trunk-cm-csel-hash/channels/chan_misdn.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=47429&r1=47428&r2=47429
==============================================================================
--- team/group/trunk-cm-csel-hash/channels/chan_misdn.c (original)
+++ team/group/trunk-cm-csel-hash/channels/chan_misdn.c Fri Nov 10 09:53:34 2006
@@ -238,12 +238,17 @@
char *ok;
};
+struct state_machine_handle_retval {
+ int state;
+ int event;
+};
+
struct state_machine_transition {
int state;
int event;
int state_next;
int event_out;
- int (*handle)(void *p, int state, int event);
+ struct state_machine_handle_retval (*handle)(void *p, int state, int event);
};
struct state_machine {
@@ -685,9 +690,10 @@
}
/* State Machine: Generic */
-#define STATE_CONTINUE -1 /*!< use this in state_next if there exists a following transition */
-#define STATE_KEEP -2 /*!< use this in state_next if you want to keep the current state */
-#define STATE_ANY -3 /*!< wildcard for the state field in struct state_machine_transision */
+#define STATE_DEFAULT -1 /*!< return value of handle(): the next state is the default one specified in the transition table */
+#define STATE_CONTINUE -2 /*!< use this in state_next if there exists a following transition */
+#define STATE_KEEP -3 /*!< use this in state_next if you want to keep the current state */
+#define STATE_ANY -4 /*!< wildcard for the state field in struct state_machine_transision */
#define EVENT_DEFAULT -1 /*!< return value of handle(): statemachine will send the event as read from the transition table */
#define EVENT_BREAK -2 /*!< return value of handle(): no event will be sent out, state_machine_run returns success */
@@ -696,6 +702,14 @@
#define LOG_RECEIVE 0 /*!< passed to log callback when receiving events */
#define LOG_TRANSMIT 1 /*!< passed to log callback when transmitting events */
+
+#define RE_STATE_EVENT(state,event) ({ struct state_machine_handle_retval rv = { (state), (event) }; rv; })
+#define RE_DEFAULT RE_STATE_EVENT(STATE_DEFAULT, EVENT_DEFAULT)
+#define RE_EVENT(event) RE_STATE_EVENT(STATE_DEFAULT, (event))
+#define RE_STATE_DEFEVENT(state) RE_STATE_EVENT((state), EVENT_DEFAULT)
+#define RE_STATE_NOEVENT(state) RE_STATE_EVENT((state), EVENT_NONE)
+#define RE_BREAK RE_STATE_EVENT(STATE_DEFAULT, EVENT_BREAK)
+#define RE_NONE RE_STATE_EVENT(STATE_DEFAULT, EVENT_NONE)
static struct state_machine * state_machine_create (void *p,
int state,
@@ -731,11 +745,13 @@
static int state_machine_run (struct state_machine *sm, int event)
{
struct state_machine_transition *t;
+ struct state_machine_handle_retval handle_retval;
int i = 0,
event_out = EVENT_DEFAULT,
err,
retval = -1,
- state = sm->state;
+ state = sm->state,
+ leave = 0;
if (sm->log_event)
sm->log_event(sm->p, LOG_RECEIVE, sm->state, event);
@@ -744,9 +760,16 @@
t = &sm->table[i];
if ((t->state == state || t->state == STATE_ANY) &&
(t->event == event || t->event == EVENT_ANY)) {
- if (t->handle)
- event_out = t->handle(sm->p, sm->state, event);
- if (event_out == EVENT_DEFAULT)
+ if (t->handle) {
+ handle_retval = t->handle(sm->p, sm->state, event);
+ event_out = handle_retval.event == EVENT_DEFAULT ? t->event_out : handle_retval.event;
+ if (handle_retval.state != STATE_DEFAULT) {
+ if (handle_retval.state != STATE_KEEP)
+ sm->state = handle_retval.state;
+ retval = 0;
+ leave = 1;
+ }
+ } else
event_out = t->event_out;
switch (event_out) {
case EVENT_BREAK:
@@ -763,6 +786,8 @@
goto out;
}
}
+ if (leave)
+ goto out;
event_out = EVENT_DEFAULT;
if (t->state_next == STATE_CONTINUE)
continue;
@@ -774,7 +799,6 @@
}
out:
- chan_misdn_log(2, 0, "state_machine_run: Returning with value %d ...\n", retval);
return retval;
}
@@ -789,24 +813,24 @@
}
/* State Machine: mISDN */
-static int handle_aevent_hangup (void *p, int state, int event);
-static int handle_mevent_setup (void *p, int state, int event);
-static int handle_mevent_setup_followup (void *p, int state, int event);
-static int handle_mevent_information (void *p, int state, int event);
-static int handle_mevent_information_dtmf (void *p, int state, int event);
-static int handle_mevent_setup_acknowledge (void *p, int state, int event);
-static int handle_mevent_connect (void *p, int state, int event);
-static int handle_mevent_disconnect (void *p, int state, int event);
-static int handle_mevent_proceeding_progress (void *p, int state, int event);
-static int handle_mevent_port_alarm (void *p, int state, int event);
-static int handle_mevent_new_channel (void *p, int state, int event);
-static int handle_mevent_new_l3id (void *p, int state, int event);
-static int handle_mevent_dtmf_tone (void *p, int state, int event);
-static int handle_mevent_alerting (void *p, int state, int event);
-static int handle_mevent_connect_acknowledge (void *p, int state, int event);
-static int handle_mevent_release (void *p, int state, int event);
-static int handle_mevent_release_complete (void *p, int state, int event);
-static int handle_mevent_cleanup (void *p, int state, int event);
+static struct state_machine_handle_retval handle_aevent_hangup (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_setup (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_setup_followup (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_information (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_information_dtmf (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_setup_acknowledge (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_connect (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_disconnect (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_proceeding_progress (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_port_alarm (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_new_channel (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_new_l3id (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_dtmf_tone (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_alerting (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_connect_acknowledge (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_release (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_release_complete (void *p, int state, int event);
+static struct state_machine_handle_retval handle_mevent_cleanup (void *p, int state, int event);
static struct state_machine_transition misdn_state_table[] = {
/*
@@ -3215,7 +3239,7 @@
return 0;
}
-static int handle_aevent_hangup (void *p, int state, int event)
+static struct state_machine_handle_retval handle_aevent_hangup (void *p, int state, int event)
{
struct chan_list *ch = p;
struct misdn_bchannel *bc = ch->bc;
@@ -3261,7 +3285,7 @@
re = EVENT_RELEASE;
}
- return re;
+ return RE_EVENT(re);
}
static int misdn_answer (struct ast_channel *ast)
@@ -3629,7 +3653,7 @@
}
/* misdn event handler functions, called by state machine on event */
-static int handle_mevent_setup (void *p, int state, int event)
+static struct state_machine_handle_retval handle_mevent_setup (void *p, int state, int event)
{
struct chan_list *ch = p;
struct misdn_bchannel *bc = ch->bc;
@@ -3643,16 +3667,15 @@
if (allowed_bearers[i].cap == bc->capability && !strstr(ch->allowed_bearers, allowed_bearers[i].name)) {
chan_misdn_log(0, bc->port, "Bearer Not allowed!\b");
bc->out_cause = 88;
- state_machine_set_state(ch->sm, MISDN_EXTCANTMATCH);
- return EVENT_RELEASE_COMPLETE;
+ return RE_STATE_EVENT(MISDN_EXTCANTMATCH, EVENT_RELEASE_COMPLETE);
}
}
}
- return EVENT_DEFAULT;
-}
-
-static int handle_mevent_setup_followup (void *p, int state, int event)
+ return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_setup_followup (void *p, int state, int event)
{
struct chan_list *ch = p;
struct misdn_bchannel *bc = ch->bc;
@@ -3662,15 +3685,15 @@
/* Check for Pickup Request first */
if (!strcmp(ch->ast->exten, ast_pickup_ext())) {
misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE);
- if (ast_pickup_call(ch->ast))
+ if (ast_pickup_call(ch->ast)) {
hangup_chan(ch);
- else {
- state_machine_set_state(ch->sm, MISDN_CALLING_ACKNOWLEDGE);
+ return RE_BREAK;
+ } else {
ast_setstate(ch->ast, AST_STATE_DOWN);
hangup_chan(ch);
ch->ast = NULL;
- }
- return EVENT_BREAK;
+ return RE_STATE_NOEVENT(MISDN_CALLING_ACKNOWLEDGE);
+ }
}
/* check if we should jump into s when we have no dad */
@@ -3690,10 +3713,8 @@
chan_misdn_log(-1, bc->port, "Extension can never match, so disconnecting\n");
if (bc->nt)
hanguptone_indicate(ch);
- state_machine_set_state(ch->sm, MISDN_EXTCANTMATCH);
bc->out_cause = 1;
- misdn_lib_send_event(bc, bc->nt ? EVENT_RELEASE_COMPLETE : EVENT_RELEASE);
- return EVENT_BREAK;
+ return RE_STATE_EVENT(MISDN_EXTCANTMATCH, bc->nt ? EVENT_RELEASE_COMPLETE : EVENT_RELEASE);
}
if (state == MISDN_WAITING4DIGS && ch->overlap_dial) {
@@ -3702,11 +3723,11 @@
ast_mutex_unlock(&ch->overlap_tv_lock);
if (ch->overlap_dial_task == -1)
ch->overlap_dial_task = misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch);
- return EVENT_BREAK;
+ return RE_BREAK;
}
if (!ch->overlap_dial && ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
- START_PBX:
+START_PBX:
state_machine_set_state(ch->sm, MISDN_DIALING);
misdn_lib_send_event(bc, (bc->nt || (bc->need_more_infos && misdn_lib_is_ptp(bc->port))) ?
EVENT_SETUP_ACKNOWLEDGE : EVENT_PROCEEDING);
@@ -3717,12 +3738,12 @@
hanguptone_indicate(ch);
misdn_lib_send_event(bc, bc->nt ? EVENT_RELEASE_COMPLETE : EVENT_RELEASE);
}
+ return RE_BREAK;
} else {
if (bc->sending_complete) {
- state_machine_set_state(ch->sm, MISDN_EXTCANTMATCH);
bc->out_cause = 1;
chan_misdn_log(0, bc->port, " --> sending_complete so we never match ..\n");
- misdn_lib_send_event(bc, bc->nt ? EVENT_RELEASE_COMPLETE : EVENT_RELEASE);
+ return RE_STATE_EVENT(MISDN_EXTCANTMATCH, bc->nt ? EVENT_RELEASE_COMPLETE : EVENT_RELEASE);
} else {
if (misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE) == -ENOCHAN) {
ast_log(LOG_WARNING, "Channel was catched before we could acknowledge!\n");
@@ -3733,7 +3754,6 @@
stop_indicate(ch);
else
dialtone_indicate(ch);
- state_machine_set_state(ch->sm, MISDN_WAITING4DIGS);
if (ch->overlap_dial && !dad_len) {
ast_mutex_lock(&ch->overlap_tv_lock);
ch->overlap_tv = ast_tvnow();
@@ -3741,13 +3761,12 @@
if (ch->overlap_dial_task == -1)
ch->overlap_dial_task = misdn_tasks_add_variable(ch->overlap_dial, misdn_overlap_dial_task, ch);
}
- }
- }
-
- return EVENT_BREAK;
-}
-
-static int handle_mevent_information (void *p, int state, int event)
+ return RE_STATE_EVENT(MISDN_WAITING4DIGS, EVENT_BREAK);
+ }
+ }
+}
+
+static struct state_machine_handle_retval handle_mevent_information (void *p, int state, int event)
{
struct chan_list *ch = p;
struct misdn_bchannel *bc = ch->bc;
@@ -3763,10 +3782,10 @@
strncpy(ch->ast->exten, bc->dad, sizeof(ch->ast->exten));
ch->ast->exten[sizeof(ch->ast->exten) - 1] = 0;
- return EVENT_DEFAULT;
-}
-
-static int handle_mevent_information_dtmf (void *p, int state, int event)
+ return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_information_dtmf (void *p, int state, int event)
{
struct chan_list *ch = p;
struct misdn_bchannel *bc = ch->bc;
@@ -3784,10 +3803,10 @@
fr.delivery = ast_tv(0, 0);
ast_queue_frame(ch->ast, &fr);
- return EVENT_DEFAULT;
-}
-
-static int handle_mevent_setup_acknowledge (void *p, int state, int event)
+ return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_setup_acknowledge (void *p, int state, int event)
{
struct chan_list *ch = p;
struct misdn_bchannel *bc = ch->bc;
@@ -3803,13 +3822,13 @@
strncpy(bc->info_dad, bc->infos_pending, sizeof(bc->info_dad));
bc->info_dad[sizeof(bc->info_dad) - 1] = 0;
*bc->infos_pending = 0;
- return EVENT_INFORMATION;
- }
-
- return EVENT_DEFAULT;
-}
-
-static int handle_mevent_connect (void *p, int state, int event)
+ return RE_EVENT(EVENT_INFORMATION);
+ }
+
+ return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_connect (void *p, int state, int event)
{
struct chan_list *ch = p;
struct ast_channel *bridged;
@@ -3832,10 +3851,10 @@
ch->addr = ch->bc->addr;
start_bc_tones(ch);
- return EVENT_DEFAULT;
-}
-
-static int handle_mevent_disconnect (void *p, int state, int event)
+ return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_disconnect (void *p, int state, int event)
{
struct chan_list *ch = p,
*holded_ch;
@@ -3851,7 +3870,7 @@
* immediately releasing the call */
chan_misdn_log(2, bc->port, " --> Inband Info Avail, not sending RELEASE\n");
start_bc_tones(ch);
- return EVENT_DEFAULT;
+ return RE_DEFAULT;
}
/* Check for holded channel, to implement transfer */
holded_ch = find_holded(cl_te, bc);
@@ -3863,20 +3882,20 @@
hangup_chan(ch);
bc->out_cause = -1;
- return EVENT_DEFAULT;
-}
-
-static int handle_mevent_proceeding_progress (void *p, int state, int event)
+ return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_proceeding_progress (void *p, int state, int event)
{
struct chan_list *ch = p;
if (misdn_cap_is_speech(ch->bc->capability) && misdn_inband_avail(ch->bc))
start_bc_tones(ch);
- return EVENT_DEFAULT;
-}
-
-static int handle_mevent_port_alarm (void *p, int state, int event)
+ return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_port_alarm (void *p, int state, int event)
{
struct chan_list *ch = p;
int boa;
@@ -3888,27 +3907,27 @@
misdn_lib_port_block(ch->bc->port);
}
- return EVENT_DEFAULT;
-}
-
-static int handle_mevent_new_channel (void *p, int state, int event)
+ return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_new_channel (void *p, int state, int event)
{
struct chan_list *ch = p;
update_name(ch->ast, ch->bc->port, ch->bc->channel);
- return EVENT_DEFAULT;
-}
-
-static int handle_mevent_new_l3id (void *p, int state, int event)
+ return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_new_l3id (void *p, int state, int event)
{
struct chan_list *ch = p;
ch->l3id = ch->bc->l3_id;
ch->addr = ch->bc->addr;
- return EVENT_DEFAULT;
-}
-
-static int handle_mevent_dtmf_tone (void *p, int state, int event)
+ return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_dtmf_tone (void *p, int state, int event)
{
struct chan_list *ch = p;
struct ast_frame fr;
@@ -3923,10 +3942,10 @@
} else
chan_misdn_log(2, ch->bc->port, " --> Ingoring DTMF:%c due to bridge flags\n", ch->bc->dtmf);
- return EVENT_DEFAULT;
-}
-
-static int handle_mevent_alerting (void *p, int state, int event)
+ return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_alerting (void *p, int state, int event)
{
struct chan_list *ch = p;
struct misdn_bchannel *bc = ch->bc;
@@ -3938,10 +3957,10 @@
} else
chan_misdn_log(2, bc->port, "We have no inband Data, the other end must create ringing.\n");
- return EVENT_DEFAULT;
-}
-
-static int handle_mevent_connect_acknowledge (void *p, int state, int event)
+ return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_connect_acknowledge (void *p, int state, int event)
{
struct chan_list *ch = p;
@@ -3949,30 +3968,30 @@
ch->addr = ch->bc->addr;
start_bc_tones(ch);
- return EVENT_DEFAULT;
-}
-
-static int handle_mevent_release (void *p, int state, int event)
+ return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_release (void *p, int state, int event)
{
struct chan_list *ch = p;
ch->bc->out_cause = 16;
hangup_chan(ch);
- return ch->bc->need_release_complete ? EVENT_DEFAULT : EVENT_NONE;
-}
-
-static int handle_mevent_release_complete (void *p, int state, int event)
+ return ch->bc->need_release_complete ? RE_DEFAULT : RE_NONE;
+}
+
+static struct state_machine_handle_retval handle_mevent_release_complete (void *p, int state, int event)
{
struct chan_list *ch = p;
stop_bc_tones(ch);
hangup_chan(ch);
- return EVENT_DEFAULT;
-}
-
-static int handle_mevent_cleanup (void *p, int state, int event)
+ return RE_DEFAULT;
+}
+
+static struct state_machine_handle_retval handle_mevent_cleanup (void *p, int state, int event)
{
struct chan_list *ch = p;
@@ -3981,16 +4000,13 @@
ch->bc->cause = 27; /* Destination out of order */
hangup_chan(ch);
- return EVENT_DEFAULT;
+ return RE_DEFAULT;
}
/* 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)
{
struct chan_list *ch = find_chan_by_bc(cl_te, bc);
-
- if (event == EVENT_SETUP_ACKNOWLEDGE)
- chan_misdn_log(0,0,"SETUP_ACKNOLEDGE!!\n");
if (event != EVENT_BCHAN_DATA && event != EVENT_TONE_GENERATE) { /* Debug Only Non-Bchan */
chan_misdn_log((event == EVENT_CLEANUP && !user_data) ? 5 : 2, bc->port, "I IND :%s oad:%s dad:%s pid:%d state:%s\n",
More information about the asterisk-commits
mailing list