[svn-commits] nadi: branch group/trunk-cm-csel-hash r47721 - in /team/group/trunk-cm-csel-h...

svn-commits at lists.digium.com svn-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 svn-commits mailing list