[asterisk-commits] nadi: branch group/trunk-cm-csel-hash r47721 - in
/team/group/trunk-cm-csel-h...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Thu Nov 16 02:45:36 MST 2006
Author: nadi
Date: Thu Nov 16 03:45:35 2006
New Revision: 47721
URL: http://svn.digium.com/view/asterisk?view=rev&rev=47721
Log:
Moving statemachine from chan_misdn.c to res_statemachine.c
Added:
team/group/trunk-cm-csel-hash/include/asterisk/statemachine.h (with props)
team/group/trunk-cm-csel-hash/res/res_statemachine.c (with props)
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=47721&r1=47720&r2=47721
==============================================================================
--- team/group/trunk-cm-csel-hash/channels/chan_misdn.c (original)
+++ team/group/trunk-cm-csel-hash/channels/chan_misdn.c Thu Nov 16 03:45:35 2006
@@ -51,6 +51,7 @@
#include <sys/file.h>
#include <semaphore.h>
+#include "asterisk/statemachine.h"
#include "asterisk/configman.h"
#include "asterisk/csel.h"
#include "asterisk/hash.h"
@@ -165,7 +166,7 @@
struct chan_list {
char allowed_bearers[BUFFERSIZE];
- struct state_machine *sm;
+ struct statemachine *sm;
int need_queue_hangup;
int need_hangup;
@@ -236,28 +237,6 @@
int bytes_wrote;
char *samples;
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;
- struct state_machine_handle_retval (*handle)(void *p, int state, int event);
-};
-
-struct state_machine {
- void *p;
- int state;
- struct state_machine_transition *table;
- int num_rows;
- int (*send_event)(void *p, int event);
- void (*log_event)(void *p, int direction, int state, int event);
};
/* Global Static Variables */
@@ -689,151 +668,28 @@
}
}
-/* State Machine: Generic */
-#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 */
-#define EVENT_NONE -3 /*!< return value of handle(): no event will be sent out, state_machine_run continues */
-#define EVENT_ANY -4 /*!< wildcard for the event field in struct state_machine_transision */
-
-#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,
- struct state_machine_transition *table,
- int num_rows,
- int (*send_event)(void *p, int event),
- void (*log_event)(void *p, int direction, int state, int event))
-{
- struct state_machine *sm = malloc(sizeof(struct state_machine));
-
- chan_misdn_log(2, 0, "state_machine_create: Creating with state %d ...\n", state);
-
- if (sm) {
- sm->p = p;
- sm->state = state;
- sm->table = table;
- sm->num_rows = num_rows;
- sm->send_event = send_event;
- sm->log_event = log_event;
- }
-
- return sm;
-}
-
-static void state_machine_destroy (struct state_machine *sm)
-{
- if (sm) {
- chan_misdn_log(2, 0, "state_machine_destroy: Freeing at state %d ...\n", sm->state);
- free(sm);
- }
-}
-
-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,
- leave = 0;
-
- if (sm->log_event)
- sm->log_event(sm->p, LOG_RECEIVE, sm->state, event);
-
- for (; i < sm->num_rows; ++i) {
- t = &sm->table[i];
- if ((t->state == state || t->state == STATE_ANY) &&
- (t->event == event || t->event == EVENT_ANY)) {
- 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:
- retval = 0;
- goto out;
- case EVENT_NONE:
- break;
- default:
- if (sm->log_event)
- sm->log_event(sm->p, LOG_TRANSMIT, sm->state, event_out);
- err = sm->send_event(sm->p, event_out);
- if (err) {
- retval = err;
- goto out;
- }
- }
- if (leave)
- goto out;
- event_out = EVENT_DEFAULT;
- if (t->state_next == STATE_CONTINUE)
- continue;
- if (t->state_next != STATE_KEEP)
- sm->state = t->state_next;
- retval = 0;
- goto out;
- }
- }
-
-out:
- return retval;
-}
-
-static inline void state_machine_set_state (struct state_machine *sm, int state)
-{
- sm->state = state;
-}
-
-static inline int state_machine_get_state (struct state_machine *sm)
-{
- return sm->state;
-}
-
-/* State Machine: mISDN */
-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_handle_retval handle_mevent_facility (void *p, int state, int event);
-
-static struct state_machine_transition misdn_state_table[] = {
+/* Statemachine */
+static struct statemachine_handle_retval handle_aevent_hangup (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_setup (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_setup_followup (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_information (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_information_dtmf (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_setup_acknowledge (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_connect (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_disconnect (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_proceeding_progress (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_port_alarm (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_new_channel (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_new_l3id (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_dtmf_tone (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_alerting (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_connect_acknowledge (void *p, int state, int event);
+static struct statemachine_handle_retval handle_mevent_release (void *p, int state, int event);
+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_transition misdn_state_table[] = {
/*
* ASTERISK EVENTS
*/
@@ -1026,7 +882,7 @@
IF_INFO(L_INFODAD, "infodad:%s", ch->bc->info_dad);
IF_INFO(L_PRES, "pres:%d", ch->bc->pres);
IF_INFO(L_SCREEN, "screen:%d", ch->bc->screen);
- IF_INFO(L_STATE, "state:%s", get_state_string(state_machine_get_state(ch->sm)));
+ IF_INFO(L_STATE, "state:%s", get_state_string(statemachine_get_state(ch->sm)));
IF_INFO(L_BCSTATE, "bc_state:%s", bc_state2str(ch->bc->bc_state));
IF_INFO(L_CONTEXT, "ctx:%s", ch->context);
}
@@ -1177,8 +1033,8 @@
return NULL;
}
- cl->sm = state_machine_create(cl, MISDN_NOTHING, misdn_state_table,
- sizeof(misdn_state_table) / sizeof(struct state_machine_transition),
+ cl->sm = statemachine_create(cl, MISDN_NOTHING, misdn_state_table,
+ sizeof(misdn_state_table) / sizeof(struct statemachine_transition),
send_event,
log_event);
cl->orginator = orig;
@@ -1260,8 +1116,8 @@
{
for (; list; list = list->next) {
chan_misdn_log(4, bc->port, "$$$ find_holded: --> holded:%d channel:%d\n",
- state_machine_get_state(list->sm) == MISDN_HOLDED, list->hold_info.channel);
- if (state_machine_get_state(list->sm) == MISDN_HOLDED && list->hold_info.port == bc->port)
+ statemachine_get_state(list->sm) == MISDN_HOLDED, list->hold_info.channel);
+ if (statemachine_get_state(list->sm) == MISDN_HOLDED && list->hold_info.port == bc->port)
return list;
}
@@ -1272,7 +1128,7 @@
static struct chan_list * find_holded_l3 (struct chan_list *list, unsigned long l3_id, int w)
{
for (; list; list = list->next)
- if (state_machine_get_state(list->sm) == MISDN_HOLDED && list->l3id == l3_id)
+ if (statemachine_get_state(list->sm) == MISDN_HOLDED && list->l3id == l3_id)
return list;
return NULL;
@@ -1609,7 +1465,7 @@
ast ? AST_CID_P(ast) : "",
bc->rad,
ast ? ast->context : "",
- get_state_string(state_machine_get_state(help->sm)));
+ get_state_string(statemachine_get_state(help->sm)));
if (misdn_debug[bc->port] > 0)
ast_cli(fd,
@@ -1830,7 +1686,7 @@
ast->hangupcause = bc->cause;
if (bc->cause == 21 || bc->cause == 17) {
- state_machine_set_state(ch->sm, MISDN_BUSY);
+ statemachine_set_state(ch->sm, MISDN_BUSY);
if (!ch->need_busy) {
chan_misdn_log(2, bc->port, "Queued busy already\n");
} else {
@@ -1968,7 +1824,7 @@
if (ast && MISDN_ASTERISK_TECH_PVT(ast)) {
chan_misdn_log(2, bc->port, "* RELEASING CHANNEL pid:%d ctx:%s dad:%s oad:%s state: %s\n",
- bc->pid, ast->context, ast->exten, AST_CID_P(ast), get_state_string(state_machine_get_state(ch->sm)));
+ bc->pid, ast->context, ast->exten, AST_CID_P(ast), get_state_string(statemachine_get_state(ch->sm)));
chan_misdn_log(3, bc->port, " --> * State Down\n");
MISDN_ASTERISK_TECH_PVT(ast) = NULL;
if (ast->_state != AST_STATE_RESERVED) {
@@ -1978,16 +1834,16 @@
}
cl_dequeue_chan(&cl_te, ch);
- state_machine_destroy(ch->sm);
+ statemachine_destroy(ch->sm);
free(ch);
}
static void misdn_transfer_bc (struct chan_list *tmp_ch, struct chan_list *holded_chan)
{
chan_misdn_log(4, 0, "TRANSFERING %s to %s\n", holded_chan->ast->name, tmp_ch->ast->name);
- state_machine_set_state(tmp_ch->sm, MISDN_HOLD_DISCONNECT);
+ statemachine_set_state(tmp_ch->sm, MISDN_HOLD_DISCONNECT);
ast_moh_stop(AST_BRIDGED_P(holded_chan->ast));
- state_machine_set_state(holded_chan->sm, MISDN_CONNECTED);
+ statemachine_set_state(holded_chan->sm, MISDN_CONNECTED);
/* misdn_lib_transfer(holded_chan->bc); */
ast_channel_masquerade(holded_chan->ast, AST_BRIDGED_P(tmp_ch->ast));
}
@@ -2035,9 +1891,9 @@
int diff;
struct chan_list *ch = (struct chan_list *)data;
- chan_misdn_log(4, ch->bc->port, "overlap dial task, chan_state: %d\n", state_machine_get_state(ch->sm));
-
- if (state_machine_get_state(ch->sm) != MISDN_WAITING4DIGS) {
+ chan_misdn_log(4, ch->bc->port, "overlap dial task, chan_state: %d\n", statemachine_get_state(ch->sm));
+
+ if (statemachine_get_state(ch->sm) != MISDN_WAITING4DIGS) {
ch->overlap_dial_task = -1;
return 0;
}
@@ -2055,7 +1911,7 @@
/* if we are 100ms near the timeout, we are satisfied.. */
stop_indicate(ch);
if (ast_exists_extension(ch->ast, ch->context, ch->bc->dad, 1, ch->bc->oad)) {
- state_machine_set_state(ch->sm, MISDN_DIALING);
+ statemachine_set_state(ch->sm, MISDN_DIALING);
if (pbx_start_chan(ch) < 0) {
chan_misdn_log(-1, ch->bc->port, "ast_pbx_start returned < 0 in misdn_overlap_dial_task\n");
goto misdn_overlap_dial_task_disconnect;
@@ -2253,7 +2109,7 @@
if (bc) {
print_bc_info(fd, help, bc);
} else {
- if (state_machine_get_state(help->sm) == MISDN_HOLDED)
+ if (statemachine_get_state(help->sm) == MISDN_HOLDED)
chan_misdn_log(0, 0, "IT'S A HOLDED BC:\n --> l3_id: %x\n --> dad:%s oad:%s\n --> hold_port: %d\n --> hold_channel: %d\n",
help->l3id, ast->exten, AST_CID_P(ast), help->hold_info.port, help->hold_info.channel);
else
@@ -2954,7 +2810,7 @@
chan_misdn_log(2, bc->port, "* IND : Digit %c\n", digit);
- switch (state_machine_get_state(p->sm)) {
+ switch (statemachine_get_state(p->sm)) {
case MISDN_CALLING:
buf[0] = digit;
buf[1] = 0;
@@ -3063,8 +2919,8 @@
else
chan_misdn_log(2, port, "NO OPTS GIVEN\n");
- if ((r = state_machine_run(ch->sm, AEVENT_CALL)))
- chan_misdn_log(0, port, "state_machine_run failed on AEVENT_CALL: %d!\n", r);
+ if ((r = statemachine_run(ch->sm, AEVENT_CALL)))
+ chan_misdn_log(0, port, "statemachine_run failed on AEVENT_CALL: %d!\n", r);
/** we should have l3id after sending setup **/
ch->l3id = newbc->l3_id;
@@ -3190,7 +3046,7 @@
MISDN_ASTERISK_TECH_PVT(ast) = NULL;
p->ast = NULL;
- state = state_machine_get_state(p->sm);
+ state = statemachine_get_state(p->sm);
if (!bc ||
ast->_state == AST_STATE_RESERVED ||
@@ -3201,7 +3057,7 @@
/* between request and call */
if (!bc)
ast_log(LOG_WARNING,"Hangup with private but no bc ? state:%s l3id:%x\n",
- get_state_string(state_machine_get_state(p->sm)), p->l3id);
+ get_state_string(statemachine_get_state(p->sm)), p->l3id);
if (option_debug)
ast_log(LOG_DEBUG, "State Reserved (or nothing) => chanIsAvail\n");
cl_dequeue_chan(&cl_te, p);
@@ -3227,21 +3083,21 @@
"* IND : HANGUP\tpid:%d ctx:%s dad:%s oad:%s state:%s\n"
" --> l3id:%x\n --> cause:%d\n --> out_cause:%d\n",
p->bc ? p->bc->pid : -1, ast->context, ast->exten, AST_CID_P(ast),
- get_state_string(state_machine_get_state(p->sm)),
+ get_state_string(statemachine_get_state(p->sm)),
p->l3id, bc->cause, bc->out_cause);
- if ((re = state_machine_run(p->sm, AEVENT_HANGUP))) {
- chan_misdn_log(0, bc->port, "state_machine_run failed on AEVENT_HANGUP: %d!\n", re);
+ if ((re = statemachine_run(p->sm, AEVENT_HANGUP))) {
+ chan_misdn_log(0, bc->port, "statemachine_run failed on AEVENT_HANGUP: %d!\n", re);
return -1;
}
chan_misdn_log(2, bc->port, "Channel: %s hanguped new state:%s\n", ast->name,
- get_state_string(state_machine_get_state(p->sm)));
+ get_state_string(statemachine_get_state(p->sm)));
return 0;
}
-static struct state_machine_handle_retval handle_aevent_hangup (void *p, int state, int event)
+static struct statemachine_handle_retval handle_aevent_hangup (void *p, int state, int event)
{
struct chan_list *ch = p;
struct misdn_bchannel *bc = ch->bc;
@@ -3324,7 +3180,7 @@
ast_copy_string(p->bc->cad, p->bc->dad, sizeof(p->bc->cad));
}
- state_machine_run(p->sm, AEVENT_ANSWER);
+ statemachine_run(p->sm, AEVENT_ANSWER);
start_bc_tones(p);
@@ -3463,7 +3319,7 @@
if (!ast || !(ch = MISDN_ASTERISK_TECH_PVT(ast)))
return -1;
- if (state_machine_get_state(ch->sm) == MISDN_HOLDED) {
+ if (statemachine_get_state(ch->sm) == MISDN_HOLDED) {
chan_misdn_log(7, ch->bc ? ch->bc->port : 0, "misdn_write: Returning because holded\n");
return 0;
}
@@ -3496,7 +3352,7 @@
if (!ch->dropped_frame_cnt)
chan_misdn_log(5, ch->bc->port,
"BC not active (nor bridged) droping: %d frames addr:%x exten:%s cid:%s ch->state:%s bc_state:%d l3id:%x\n",
- frame->samples, ch->bc->addr, ast->exten, ast->cid.cid_num, get_state_string(state_machine_get_state(ch->sm)),
+ frame->samples, ch->bc->addr, ast->exten, ast->cid.cid_num, get_state_string(statemachine_get_state(ch->sm)),
ch->bc->bc_state, ch->bc->l3_id);
ch->dropped_frame_cnt++;
if (ch->dropped_frame_cnt > 100) {
@@ -3536,7 +3392,7 @@
chan_misdn_log(2, p->bc->port, " --> * SEND: State Busy pid:%d\n", p->bc->pid);
ast_setstate(ast, AST_STATE_BUSY);
p->bc->out_cause = 17;
- if (state_machine_get_state(p->sm) != MISDN_CONNECTED) {
+ if (statemachine_get_state(p->sm) != MISDN_CONNECTED) {
start_bc_tones(p);
misdn_lib_send_event(p->bc, EVENT_DISCONNECT);
} else
@@ -3546,7 +3402,7 @@
chan_misdn_log(2, p->bc->port, " --> * IND :\tring pid:%d\n", p->bc->pid);
return -1;
case AST_CONTROL_RINGING:
- switch (state_machine_get_state(p->sm)) {
+ switch (statemachine_get_state(p->sm)) {
case MISDN_ALERTING:
chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but I was Ringing before, so ignoreing it\n", p->bc->pid);
break;
@@ -3554,7 +3410,7 @@
chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d but Connected, so just send TONE_ALERTING without state changes \n", p->bc->pid);
return -1;
default:
- state_machine_set_state(p->sm, MISDN_ALERTING);
+ statemachine_set_state(p->sm, MISDN_ALERTING);
chan_misdn_log(2, p->bc->port, " --> * IND :\tringing pid:%d\n", p->bc->pid);
misdn_lib_send_event(p->bc, EVENT_ALERTING);
if (p->other_ch && p->other_ch->bc) {
@@ -3599,7 +3455,7 @@
case AST_CONTROL_CONGESTION:
chan_misdn_log(2, p->bc->port, " --> * IND :\tcongestion pid:%d\n", p->bc->pid);
p->bc->out_cause = 42;
- if (state_machine_get_state(p->sm) != MISDN_CONNECTED) {
+ if (statemachine_get_state(p->sm) != MISDN_CONNECTED) {
start_bc_tones(p);
misdn_lib_send_event(p->bc, EVENT_RELEASE);
} else
@@ -3610,7 +3466,7 @@
case -1:
chan_misdn_log(2, p->bc->port, " --> * IND :\t-1! (stop indication) pid:%d\n", p->bc->pid);
stop_indicate(p);
- if (state_machine_get_state(p->sm) == MISDN_CONNECTED)
+ if (statemachine_get_state(p->sm) == MISDN_CONNECTED)
start_bc_tones(p);
break;
case AST_CONTROL_HOLD:
@@ -3633,9 +3489,9 @@
if (!ast || !(p = MISDN_ASTERISK_TECH_PVT(ast)))
return -1;
- chan_misdn_log(2, p->bc ? p->bc->port : 0, "* IND: Got Fixup State:%s L3id:%x\n", get_state_string(state_machine_get_state(p->sm)), p->l3id);
+ chan_misdn_log(2, p->bc ? p->bc->port : 0, "* IND: Got Fixup State:%s L3id:%x\n", get_state_string(statemachine_get_state(p->sm)), p->l3id);
p->ast = ast;
- state_machine_set_state(p->sm, MISDN_FIXUP);
+ statemachine_set_state(p->sm, MISDN_FIXUP);
return 0;
}
@@ -3654,8 +3510,8 @@
return 0;
}
-/* misdn event handler functions, called by state machine on event */
-static struct state_machine_handle_retval handle_mevent_setup (void *p, int state, int event)
+/* misdn event handler functions, called by statemachine on event */
+static struct statemachine_handle_retval handle_mevent_setup (void *p, int state, int event)
{
struct chan_list *ch = p;
struct misdn_bchannel *bc = ch->bc;
@@ -3677,7 +3533,7 @@
return RE_DEFAULT;
}
-static struct state_machine_handle_retval handle_mevent_setup_followup (void *p, int state, int event)
+static struct statemachine_handle_retval handle_mevent_setup_followup (void *p, int state, int event)
{
struct chan_list *ch = p;
struct misdn_bchannel *bc = ch->bc;
@@ -3730,7 +3586,7 @@
if (!ch->overlap_dial && ast_exists_extension(ch->ast, ch->context, bc->dad, 1, bc->oad)) {
START_PBX:
- state_machine_set_state(ch->sm, MISDN_DIALING);
+ statemachine_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);
if (pbx_start_chan(ch) < 0) {
@@ -3768,7 +3624,7 @@
}
}
-static struct state_machine_handle_retval handle_mevent_information (void *p, int state, int event)
+static struct statemachine_handle_retval handle_mevent_information (void *p, int state, int event)
{
struct chan_list *ch = p;
struct misdn_bchannel *bc = ch->bc;
@@ -3787,7 +3643,7 @@
return RE_DEFAULT;
}
-static struct state_machine_handle_retval handle_mevent_information_dtmf (void *p, int state, int event)
+static struct statemachine_handle_retval handle_mevent_information_dtmf (void *p, int state, int event)
{
struct chan_list *ch = p;
struct misdn_bchannel *bc = ch->bc;
@@ -3808,7 +3664,7 @@
return RE_DEFAULT;
}
-static struct state_machine_handle_retval handle_mevent_setup_acknowledge (void *p, int state, int event)
+static struct statemachine_handle_retval handle_mevent_setup_acknowledge (void *p, int state, int event)
{
struct chan_list *ch = p;
struct misdn_bchannel *bc = ch->bc;
@@ -3830,7 +3686,7 @@
return RE_DEFAULT;
}
-static struct state_machine_handle_retval handle_mevent_connect (void *p, int state, int event)
+static struct statemachine_handle_retval handle_mevent_connect (void *p, int state, int event)
{
struct chan_list *ch = p;
struct ast_channel *bridged;
@@ -3856,7 +3712,7 @@
return RE_DEFAULT;
}
-static struct state_machine_handle_retval handle_mevent_disconnect (void *p, int state, int event)
+static struct statemachine_handle_retval handle_mevent_disconnect (void *p, int state, int event)
{
struct chan_list *ch = p,
*holded_ch;
@@ -3887,7 +3743,7 @@
return RE_DEFAULT;
}
-static struct state_machine_handle_retval handle_mevent_proceeding_progress (void *p, int state, int event)
+static struct statemachine_handle_retval handle_mevent_proceeding_progress (void *p, int state, int event)
{
struct chan_list *ch = p;
@@ -3897,7 +3753,7 @@
return RE_DEFAULT;
}
-static struct state_machine_handle_retval handle_mevent_port_alarm (void *p, int state, int event)
+static struct statemachine_handle_retval handle_mevent_port_alarm (void *p, int state, int event)
{
struct chan_list *ch = p;
int boa;
@@ -3912,14 +3768,14 @@
return RE_DEFAULT;
}
-static struct state_machine_handle_retval handle_mevent_new_channel (void *p, int state, int event)
+static struct statemachine_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 RE_DEFAULT;
}
-static struct state_machine_handle_retval handle_mevent_new_l3id (void *p, int state, int event)
+static struct statemachine_handle_retval handle_mevent_new_l3id (void *p, int state, int event)
{
struct chan_list *ch = p;
@@ -3929,7 +3785,7 @@
return RE_DEFAULT;
}
-static struct state_machine_handle_retval handle_mevent_dtmf_tone (void *p, int state, int event)
+static struct statemachine_handle_retval handle_mevent_dtmf_tone (void *p, int state, int event)
{
struct chan_list *ch = p;
struct ast_frame fr;
@@ -3947,7 +3803,7 @@
return RE_DEFAULT;
}
-static struct state_machine_handle_retval handle_mevent_alerting (void *p, int state, int event)
+static struct statemachine_handle_retval handle_mevent_alerting (void *p, int state, int event)
{
struct chan_list *ch = p;
struct misdn_bchannel *bc = ch->bc;
@@ -3962,7 +3818,7 @@
return RE_DEFAULT;
}
-static struct state_machine_handle_retval handle_mevent_connect_acknowledge (void *p, int state, int event)
+static struct statemachine_handle_retval handle_mevent_connect_acknowledge (void *p, int state, int event)
{
struct chan_list *ch = p;
@@ -3973,7 +3829,7 @@
return RE_DEFAULT;
}
-static struct state_machine_handle_retval handle_mevent_release (void *p, int state, int event)
+static struct statemachine_handle_retval handle_mevent_release (void *p, int state, int event)
{
struct chan_list *ch = p;
@@ -3983,7 +3839,7 @@
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)
+static struct statemachine_handle_retval handle_mevent_release_complete (void *p, int state, int event)
{
struct chan_list *ch = p;
@@ -3993,7 +3849,7 @@
return RE_DEFAULT;
}
-static struct state_machine_handle_retval handle_mevent_cleanup (void *p, int state, int event)
+static struct statemachine_handle_retval handle_mevent_cleanup (void *p, int state, int event)
{
struct chan_list *ch = p;
@@ -4005,7 +3861,7 @@
return RE_DEFAULT;
}
-static struct state_machine_handle_retval handle_mevent_facility (void *p, int state, int event)
+static struct statemachine_handle_retval handle_mevent_facility (void *p, int state, int event)
{
struct chan_list *ch = p;
struct misdn_bchannel *bc = ch->bc;
@@ -4046,7 +3902,7 @@
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",
- manager_isdn_get_info(event), bc->oad, bc->dad, bc->pid, ch ? get_state_string(state_machine_get_state(ch->sm)) : "none");
+ manager_isdn_get_info(event), bc->oad, bc->dad, bc->pid, ch ? get_state_string(statemachine_get_state(ch->sm)) : "none");
if ((event != EVENT_CLEANUP || user_data)) {
misdn_lib_log_ies(bc);
chan_misdn_log(4, bc->port, " --> bc_state:%s\n", bc_state2str(bc->bc_state));
@@ -4168,7 +4024,7 @@
int msn_valid = 0,
exceed;
if (ch) {
- if (state_machine_get_state(ch->sm) == MISDN_NOTHING)
+ if (statemachine_get_state(ch->sm) == MISDN_NOTHING)
ch = NULL;
else {
chan_misdn_log(2, bc->port, " --> Ignoring Call we already have one\n");
@@ -4228,23 +4084,23 @@
}
/*
- * run the state machine and return if the event could be handled
+ * run the statemachine and return if the event could be handled
*/
- if (ch && !state_machine_run(ch->sm, event)) {
+ if (ch && !statemachine_run(ch->sm, event)) {
if (event == EVENT_RELEASE || event == EVENT_RELEASE_COMPLETE || event == EVENT_CLEANUP)
release_chan(ch->bc);
return RESPONSE_OK;
}
/*
- * this is for events not (yet) handled by our state machine
+ * 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(state_machine_get_state(ch->sm)));
- switch (state_machine_get_state(ch->sm)) {
+ 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)
@@ -4295,7 +4151,7 @@
/*remember the channel again*/
ch->bc = bc;
- state_machine_set_state(ch->sm, MISDN_CONNECTED);
+ statemachine_set_state(ch->sm, MISDN_CONNECTED);
hold_ast = AST_BRIDGED_P(ch->ast);
if (hold_ast)
@@ -4318,7 +4174,7 @@
bridged = AST_BRIDGED_P(ch->ast);
if (bridged){
chan_misdn_log(2, bc->port, "Bridge Partner is of type: %s\n", bridged->tech->type);
- state_machine_set_state(ch->sm, MISDN_HOLDED);
+ 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
Added: team/group/trunk-cm-csel-hash/include/asterisk/statemachine.h
URL: http://svn.digium.com/view/asterisk/team/group/trunk-cm-csel-hash/include/asterisk/statemachine.h?view=auto&rev=47721
==============================================================================
--- team/group/trunk-cm-csel-hash/include/asterisk/statemachine.h (added)
+++ team/group/trunk-cm-csel-hash/include/asterisk/statemachine.h Thu Nov 16 03:45:35 2006
@@ -1,0 +1,85 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2006, Nadi Sarrar
+ *
+ * Nadi Sarrar <nadi at beronet.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file statemachine.h
+ * \brief Simple Statemachine
+ * \author Nadi Sarrar <nadi at beronet.com>
+ */
+
+#ifndef _ASTERISK_STATEMACHINE_H
+#define _ASTERISK_STATEMACHINE_H
+
+#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 statemachine_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, statemachine_run returns success */
+#define EVENT_NONE -3 /*!< return value of handle(): no event will be sent out, statemachine_run continues */
+#define EVENT_ANY -4 /*!< wildcard for the event field in struct statemachine_transision */
+
+#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 statemachine_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)
+
+struct statemachine_handle_retval {
+ int state;
+ int event;
+};
+
+struct statemachine_transition {
+ int state;
+ int event;
+ int state_next;
+ int event_out;
+ struct statemachine_handle_retval (*handle)(void *p, int state, int event);
+};
+
+struct statemachine {
+ void *p;
+ int state;
+ struct statemachine_transition *table;
+ int num_rows;
+ int (*send_event)(void *p, int event);
+ void (*log_event)(void *p, int direction, int state, int event);
+};
+
+struct statemachine * statemachine_create (void *p,
+ int state,
+ struct statemachine_transition *table,
+ int num_rows,
+ int (*send_event)(void *p, int event),
+ void (*log_event)(void *p, int direction, int state, int event));
+
+void statemachine_destroy (struct statemachine *sm);
+
+int statemachine_run (struct statemachine *sm, int event);
+
+int statemachine_get_state (struct statemachine *sm);
+
+void statemachine_set_state (struct statemachine *sm, int state);
+
+#endif
Propchange: team/group/trunk-cm-csel-hash/include/asterisk/statemachine.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/group/trunk-cm-csel-hash/include/asterisk/statemachine.h
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/group/trunk-cm-csel-hash/include/asterisk/statemachine.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: team/group/trunk-cm-csel-hash/res/res_statemachine.c
URL: http://svn.digium.com/view/asterisk/team/group/trunk-cm-csel-hash/res/res_statemachine.c?view=auto&rev=47721
==============================================================================
--- team/group/trunk-cm-csel-hash/res/res_statemachine.c (added)
+++ team/group/trunk-cm-csel-hash/res/res_statemachine.c Thu Nov 16 03:45:35 2006
@@ -1,0 +1,162 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2006, Nadi Sarrar
+ *
+ * Nadi Sarrar <nadi at beronet.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file res_statemachine.c
+ *
+ * \brief Simple Statemachine
+ *
+ * \author Nadi Sarrar <nadi at beronet.com>
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/statemachine.h"
+#include "asterisk/module.h"
+#include "asterisk/logger.h"
+#include "asterisk/lock.h"
+#include "asterisk/utils.h"
+#include "asterisk/cli.h"
+#include "asterisk/term.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+/* State Machine: Generic */
+struct statemachine * statemachine_create (void *p,
+ int state,
+ struct statemachine_transition *table,
+ int num_rows,
+ int (*send_event)(void *p, int event),
+ void (*log_event)(void *p, int direction, int state, int event))
+{
+ struct statemachine *sm = malloc(sizeof(struct statemachine));
+
+ if (sm) {
+ ast_module_ref(ast_module_info->self);
+ ast_log(LOG_VERBOSE, "Creating statemachine with state %d ...\n", state);
+ sm->p = p;
+ sm->state = state;
+ sm->table = table;
+ sm->num_rows = num_rows;
+ sm->send_event = send_event;
+ sm->log_event = log_event;
+ }
+
+ return sm;
+}
+
+void statemachine_destroy (struct statemachine *sm)
+{
+ if (sm) {
+ ast_log(LOG_VERBOSE, "Destroying statemachine at state %d ...\n", sm->state);
+ free(sm);
+ ast_module_unref(ast_module_info->self);
+ }
+}
+
+int statemachine_run (struct statemachine *sm, int event)
+{
+ struct statemachine_transition *t;
+ struct statemachine_handle_retval handle_retval;
+ int i = 0,
+ event_out = EVENT_DEFAULT,
+ err,
+ retval = -1,
+ state = sm->state,
+ leave = 0;
+
+ if (sm->log_event)
+ sm->log_event(sm->p, LOG_RECEIVE, sm->state, event);
+
+ for (; i < sm->num_rows; ++i) {
+ t = &sm->table[i];
+ if ((t->state == state || t->state == STATE_ANY) &&
+ (t->event == event || t->event == EVENT_ANY)) {
+ 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:
+ retval = 0;
+ goto out;
+ case EVENT_NONE:
+ break;
+ default:
+ if (sm->log_event)
+ sm->log_event(sm->p, LOG_TRANSMIT, sm->state, event_out);
+ err = sm->send_event(sm->p, event_out);
+ if (err) {
+ retval = err;
+ goto out;
+ }
+ }
+ if (leave)
+ goto out;
+ event_out = EVENT_DEFAULT;
+ if (t->state_next == STATE_CONTINUE)
+ continue;
+ if (t->state_next != STATE_KEEP)
+ sm->state = t->state_next;
+ retval = 0;
+ goto out;
+ }
+ }
+
+out:
+ return retval;
+}
+
+int statemachine_get_state (struct statemachine *sm)
+{
+ return sm->state;
+}
+void statemachine_set_state (struct statemachine *sm, int state)
+{
+ sm->state = state;
+}
+
+static int load_module (void)
+{
+ return 0;
+}
+
+static int unload_module (void)
+{
+ return 0;
+}
+
+static int reload (void)
+{
+ return -1;
+}
+
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS, "Statemachine Resource",
+ .load = load_module,
+ .unload = unload_module,
+ .reload = reload,
+ );
Propchange: team/group/trunk-cm-csel-hash/res/res_statemachine.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/group/trunk-cm-csel-hash/res/res_statemachine.c
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Propchange: team/group/trunk-cm-csel-hash/res/res_statemachine.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the asterisk-commits
mailing list