Main finite state machine for G3-fax transfers.

This commit is contained in:
Morten Rolland 1999-03-21 15:29:34 +00:00
parent 082627a20c
commit 91bc735b20
2 changed files with 306 additions and 0 deletions

275
G3/fsm.c Normal file
View File

@ -0,0 +1,275 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Main state-machine for G3-fax handeling.
Copyright (C) 1999 Morten Rolland [Morten.Rolland@asker.mail.telia.com]
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************
*/
/* This file contains all the states and their related logic needed to
* implement a G3-fax encoder/decoder. It is important to notice that
* the states of this state-machine may not always map directly to
* the G3-fax specifications. The reason for this is the fact that
* everything is handeled in software in this implementation, and that
* extra states and logic may be needed to handle problems usually
* handled by hardware directely.
*/
#include <ifax/types.h>
#include <ifax/G3/fax.h>
#include <ifax/G3/kernel.h>
#include <ifax/G3/g3-timers.h>
#include <ifax/misc/timers.h>
#include <ifax/misc/softsignals.h>
/* All timing is done in units of 1/8000 seconds (one ISDN-sample) */
#define SEVENTYFIVEMILLISECONDS 600
#define ZEROPOINTTWOSECONDS 1600
#define THREEPOINTEIGHTSECONDS 30400
/* Use the following macros when defining the states */
#define STATE(x) static void x(struct G3fax *fax)
#define DEFSTATE(x) static void x(struct G3fax *);
/* When waiting for a specified ammount of time, and doing nothing
* else, the simple_wait() function can be used. It simply inserts
* a "waiting-state" into the flow of things, using the TIMER_AUX
* timer, and jumps to the specified "next-state" once the wait
* is over.
*/
STATE(simple_wait_state)
{
if ( softsignaled(TIMER_AUX) )
fax->fsm = fax->simple_wait_next_state;
}
void simple_wait(struct G3fax *fax, ifax_sint32 delay,
void (*state)(struct G3fax *))
{
fax->simple_wait_next_state = state;
fax->fsm = simple_wait_state;
one_shot_timer(TIMER_AUX,delay);
}
/* The following states are subroutines that must be called by means
* of the 'invoke_subroutine' function.
*/
/* DEFSTATE(response_received) */
/* List states here that is called in a forward fashion (most of them) */
DEFSTATE(start_answer_incomming)
DEFSTATE(do_CED)
DEFSTATE(done_CED)
DEFSTATE(do_DIS)
/* Jump to 'start_answering_call' when an incomming call is
* accepted (answered) and we identify ourselves as a fax-machine.
* The initialize_fsm_incomming() function is used to initialize the fsm
* and signal-chain to handle an incomming call and jump to this state.
*/
void initialize_fsm_incomming(struct G3fax *fax)
{
fax->fsm = start_answer_incomming;
fax_run_internals(fax);
}
STATE(start_answer_incomming)
{
/* Stay silent for 0.2 seconds before outputing the CED */
ifax_connect(fax->silence,fax->rateconv7k2to8k0);
simple_wait(fax,ZEROPOINTTWOSECONDS,do_CED);
}
STATE(do_CED)
{
/* Output the CED sinus signal for 3.8 sec */
ifax_connect(fax->sinusCED,fax->rateconv7k2to8k0);
simple_wait(fax,THREEPOINTEIGHTSECONDS,done_CED);
}
STATE(done_CED)
{
/* After the CED, wait 75ms and do the DIS */
ifax_connect(fax->silence,fax->rateconv7k2to8k0);
simple_wait(fax,SEVENTYFIVEMILLISECONDS,do_DIS);
}
STATE(do_DIS)
{
/* Naah, we need some more modules first... */
}
#if 0
/* The following code can't be used yet, because so many other modules
* lack the softsignaling functionality when certain events occour.
* Some other modules required has not been written yet.
*/
/****************************************************************************
*
* Response Received, FIGURE 5-2s/T.30
*
* This state-machine subroutine checks if a valid response has
* arrived within the time-limits. If an illegal situation
* occours, like the remote transmitting more than it is allowed to,
* a hangup is performed.
*
* By calling the 'invoke_subroutine' on the state 'response_received',
* the answer will be available in RESPONSERECEIVED_RESULT .
*/
DEFSTATE(response_received_flag)
DEFSTATE(response_received_raf)
DEFSTATE(response_received_sg1)
DEFSTATE(response_received_sg2)
DEFSTATE(response_received_sg2_helper)
DEFSTATE(response_received_tdcn)
DEFSTATE(response_received_disconnect)
STATE(response_received)
{
one_shot_timer(TIMER_T4,THREESECONDS);
fax->fsm = response_received_flag;
}
STATE(response_received_flag)
{
if ( softsignaled_clr(HDLCFLAGDETECTED) ) {
one_shot_timer(TIMER_SHUTUP,THREESECONDS);
fax->fsm = response_received_RAF;
}
if ( softsignaled(TIMER_T4) ) {
softsignal_set(RESPONSERECEIVED_RESULT,0);
return_from_subroutine(fax);
}
}
STATE(response_received_raf)
{
if ( softsignaled_clr(HDLCFRAMERECEIVED) ) {
fax_decode_controlmsg(fax);
if ( fax->FCSerror || fax->ctrlmsg == MSG_CRP ) {
fax->fsm = response_received_sg2;
return;
}
if ( fax->ctrlmsg == MSG_DCN ) {
fax->fsm = response_received_disconnect;
return;
}
if ( process_optional_response(fax) ) {
fax->fsm = response_received_flag;
return;
}
softsignal_set(RESPONSERECEIVED_RESULT,1);
return_from_subroutine(fax);
return;
}
/* We don't have a frame with data, Check for 200 ms silence (end of
* transmission) or a runaway remote fax that keeps sending.
*/
if ( softsignaled(V21CARRIEROK) ) {
if ( softsignaled(TIMER_SHUTUP) ) {
fax->fsm = response_received_tdcn;
}
return;
}
one_shot_timer(TIMER_AUX,ZEROPOINTTWOSECONDS);
fax->fsm = response_received_sg1;
}
STATE(response_received_sg1)
{
if ( softsignaled(V21CARRIEROK ) ) {
fax->fsm = response_received_raf;
return;
}
if ( softsignaled(TIMER_AUX) ) {
softsignal_set(RESPONSERECEIVED_RESULT,0);
return_from_subroutine(fax);
}
}
STATE(response_received_sg2)
{
if ( softfignaled(V21CARRIEROK) ) {
if ( softsignaled(TIMER_SHUTUP) )
fax->fsm = response_received_tdcn;
return;
}
one_shot_timer(TIMER_AUX,ZEROPOINTTWOSECONDS);
fax->fsm = response_received_sg2_helper;
}
STATE(response_received_sg2_helper)
{
if ( softsignaled(V21CARRIEROK) ) {
fax->fsm = response_received_sg2;
return;
}
if ( softsignaled(TIMER_AUX) ) {
softsignal_set(RESPONSERECEIVED_RESULT,0);
return_from_subroutine(fax);
}
}
STATE(response_received_tdcn)
{
/* Transmit a disconnect line command */
fax->fsm = response_received_disconnect;
}
STATE(response_received_disconnect)
{
softsignal(ACTION_HANGUP);
return_from_subroutine(fax);
}
#endif

31
include/ifax/G3/fsm.h Normal file
View File

@ -0,0 +1,31 @@
/* $Id$
******************************************************************************
Fax program for ISDN.
Main state-machine for G3-fax handeling.
Copyright (C) 1999 Morten Rolland [Morten.Rolland@asker.mail.telia.com]
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
******************************************************************************
*/
#include <ifax/G3/fax.h>
extern void initialize_fsm_incomming(struct G3fax *);