749 lines
21 KiB
C
749 lines
21 KiB
C
/*--------------------------------------------------------------------------*\
|
|
|
|
FAXMAIN.C Version 1.1 1995 AVM
|
|
|
|
's'+'S' Send fax
|
|
'r'+'R' Receive fax
|
|
|
|
\*--------------------------------------------------------------------------*/
|
|
#if !defined (NDEBUG)
|
|
#define DEBUG
|
|
#define CPROT
|
|
#endif
|
|
|
|
#include "os.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <signal.h>
|
|
#include <assert.h>
|
|
|
|
#include "capi20.h"
|
|
#include "c20msg.h"
|
|
#include "capi.h"
|
|
#include "connect.h"
|
|
#include "contr.h"
|
|
#include "data.h"
|
|
#include "id.h"
|
|
#include "init.h"
|
|
#include "fax.h"
|
|
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
\*--------------------------------------------------------------------------*/
|
|
/*----- note: you may enter your own number here, but if you -----*/
|
|
/*----- supply a wrong number, some PBXs may reject the -----*/
|
|
/*----- CAPI messages containing the wrong number -----*/
|
|
/*----- e.g.: static char *CallingPartyNumber = "1234567"; -----*/
|
|
static char *CallingPartyNumber = NULL;
|
|
|
|
static char CalledPartyNumberArr[40];
|
|
|
|
#ifdef DEBUG
|
|
static char CAPI_PROT_BUF[CAPI_PROTOCOL_INIT_BUF_SIZE];
|
|
static char ProtocolFileName[80];
|
|
static FILE *ProtocolFile;
|
|
#endif
|
|
|
|
#define INVALID_SLOT -1
|
|
#define maxSlots 2 /*----- this demo program handles max. -----*/
|
|
/*----- two connections -----*/
|
|
static ConnectionID Slot[maxSlots];
|
|
|
|
|
|
#define B1PROTOCOL 4
|
|
#define B2PROTOCOL 4
|
|
#define B3PROTOCOL 4
|
|
|
|
|
|
#define QueueSize 8
|
|
|
|
typedef struct __DataElement {
|
|
char DATA[SendBlockSize];
|
|
unsigned short DATA_LENGTH;
|
|
unsigned SENT;
|
|
} _DataElement;
|
|
|
|
typedef struct __DataQueue {
|
|
_DataElement Element[QueueSize];
|
|
unsigned Head;
|
|
unsigned Tail;
|
|
unsigned Fill;
|
|
} _DataQueue;
|
|
|
|
_DataQueue Queue;
|
|
|
|
static unsigned FileTransfer = FALSE; /*----- signals if filetransfer is in progress -----*/
|
|
static unsigned FileReceive = FALSE; /*----- signals if filetransfer is in progress -----*/
|
|
static FILE *File;
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
* Press_Key:
|
|
\*--------------------------------------------------------------------------*/
|
|
int Press_Key(void) {
|
|
int c;
|
|
|
|
if ((c = getch()) == 0)
|
|
c = getch()+256;
|
|
return c;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
* GetSlot: returns the slotnumber of the ConnectionID or INVALID_SLOT
|
|
\*--------------------------------------------------------------------------*/
|
|
int GetSlot(ConnectionID Con) {
|
|
int x;
|
|
|
|
for (x=0; x<maxSlots; x++)
|
|
if (Slot[x] == Con) return x;
|
|
return INVALID_SLOT;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
* AllocSlot: allocates one slot, if none free returns INVALID_SLOT
|
|
\*--------------------------------------------------------------------------*/
|
|
int AllocSlot(ConnectionID Con) {
|
|
int x;
|
|
|
|
for (x=0; x<maxSlots; x++)
|
|
if (Slot[x] == INVALID_CONNECTION_ID) {
|
|
Slot[x] = Con;
|
|
return x;
|
|
}
|
|
return INVALID_SLOT;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
* FreeSlot: clear one slot
|
|
\*--------------------------------------------------------------------------*/
|
|
void FreeSlot(int index) {
|
|
Slot[index] = INVALID_CONNECTION_ID;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
* MainDataAvailable: signals received data blocks
|
|
* This function is called after a DATA_B3_INDication is received. The flag
|
|
* DiscardData tells CAPI to free the memora area directly after the return
|
|
* of this function when set to TRUE (1) which is the preset. When the flag
|
|
* is set to FALSE (0) the data area MUST be freed later with ReleaseData.
|
|
* The datahandle identifies the memory area. When reaching 7 unconfirmed
|
|
* blocks, no more incoming data will be signaled until freeing at least
|
|
* one block.
|
|
\*--------------------------------------------------------------------------*/
|
|
void MainDataAvailable(ConnectionID Connection,
|
|
void __far *Data,
|
|
unsigned short DataLength,
|
|
unsigned short DataHandle,
|
|
int *DiscardData) {
|
|
|
|
assert (Connection != INVALID_CONNECTION_ID);
|
|
|
|
|
|
# ifdef DEBUG
|
|
CAPI_PROTOCOL_TEXT("***** incoming data, slot %d ID %d, size %d , handle %u *****\n",
|
|
GetSlot(Connection), Connection, DataLength, DataHandle);
|
|
# endif
|
|
|
|
if ((FileReceive) && (File != NULL)) {
|
|
fwrite(Data, 1, DataLength, File);
|
|
}
|
|
*DiscardData = TRUE;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
* MainDataConf: signals the successful sending of a datablock
|
|
* This function is called after receiving a DATA_B3_CONFirmation. CAPI signals
|
|
* that the datablock identified by DataHandle has been sent and the memory
|
|
* area may be freed. The DataHandle is the same as specified in SendBlock.
|
|
\*--------------------------------------------------------------------------*/
|
|
void MainDataConf(ConnectionID Connection,
|
|
unsigned short DataHandle,
|
|
unsigned short Info) {
|
|
|
|
assert (Connection != INVALID_CONNECTION_ID);
|
|
|
|
|
|
if (Info != 0) {
|
|
# ifdef DEBUG
|
|
CAPI_PROTOCOL_TEXT("***** datablock slot %d ID %d handle %d NOT sent , error: 0x%04X *****\n",
|
|
GetSlot(Connection), Connection, DataHandle, Info);
|
|
# endif
|
|
return;
|
|
}
|
|
if (FileTransfer) {
|
|
|
|
assert (DataHandle == (unsigned short)Queue.Tail);
|
|
|
|
Queue.Element[Queue.Tail].SENT = FALSE;
|
|
if (++Queue.Tail >= QueueSize) Queue.Tail = 0;
|
|
Queue.Fill--;
|
|
}
|
|
# ifdef DEBUG
|
|
CAPI_PROTOCOL_TEXT("***** datablock slot %d ID %d handle %d has been sent *****\n",
|
|
GetSlot(Connection), Connection, DataHandle);
|
|
# endif
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
* MainStateChange: signals a state change on both B-channels (connected,
|
|
* disconnected). Whenever a channel changes his state this function is called
|
|
\*--------------------------------------------------------------------------*/
|
|
void MainStateChange(ConnectionID Connection,
|
|
ConnectionState State) {
|
|
int index;
|
|
|
|
assert (Connection != INVALID_CONNECTION_ID);
|
|
|
|
|
|
index = GetSlot(Connection);
|
|
# ifdef DEBUG
|
|
CAPI_PROTOCOL_TEXT("***** state change slot %d ID %d: %s *****\n", index, Connection,
|
|
ConnectionStateString[State]);
|
|
# endif
|
|
|
|
if (State == Disconnected) {
|
|
FreeSlot(index);
|
|
}
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
* MainIncomingCall: signals an incoming call
|
|
* This function will be executed if a CONNECT_INDication appears to
|
|
* inform the user.
|
|
\*--------------------------------------------------------------------------*/
|
|
void MainIncomingCall(ConnectionID Connection,
|
|
char *CallingPartyNumber) {
|
|
|
|
int index;
|
|
B3_PROTO_FAXG3 B3conf;
|
|
|
|
assert (Connection != INVALID_CONNECTION_ID);
|
|
|
|
|
|
# ifdef DEBUG
|
|
CAPI_PROTOCOL_TEXT("***** incoming call ,ID %d, caller: \"%s\" *****\n",Connection,CallingPartyNumber);
|
|
# endif
|
|
index = AllocSlot(Connection);
|
|
|
|
SetupB3Config( &B3conf, FAX_SFF_FORMAT);
|
|
|
|
if (index == INVALID_SLOT) {
|
|
# ifdef DEBUG
|
|
CAPI_PROTOCOL_TEXT("***** no free slot available, rejecting call... *****\n");
|
|
# endif
|
|
AnswerCall(Connection, REJECT, 4, 4, 4, (_cstruct)&B3conf);
|
|
return;
|
|
}
|
|
# ifdef DEBUG
|
|
CAPI_PROTOCOL_TEXT("***** call assigned to slot %d *****\n", index);
|
|
# endif
|
|
|
|
AnswerCall(Connection, ACCEPT, 4, 4, 4, (_cstruct)&B3conf);
|
|
}
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
* CAPI_PROT_HANDLE: This is a callback-function that has been specified
|
|
* with CAPI_PROTOCOL_INIT. The first parameter is a pointer to the protocol-
|
|
* message which is plain ASCII-text. The parameter t contains the type of
|
|
* the message which can be CAPI_PROTOCOL_HEADER (appears only once when
|
|
* calling CAPI_PROTOCOL_INIT), CAPI_PROTOCOL_MSG (the text contains a
|
|
* decoded CAPI-message) and CAPI_PROTOCOL_TXT (the buffers contains a debug
|
|
* message or a message sent with the function CAPI_PROTOCOL_TEXT).
|
|
* If the type of the message is CAPI_PROTOCOL_MSG, the last parameter contains
|
|
* a pointer to the decoded CAPI-message.
|
|
\*--------------------------------------------------------------------------*/
|
|
void CAPI_PROT_HANDLE(char *Message,
|
|
CAPI_PROTOCOL_TYP t,
|
|
CAPI_MESSAGE m) {
|
|
|
|
fprintf(ProtocolFile,"%s",Message);
|
|
if (t != CAPI_PROTOCOL_MSG)
|
|
puts(Message);
|
|
|
|
if (t == CAPI_PROTOCOL_MSG) {
|
|
_cmsg CMSG;
|
|
|
|
CAPI_MESSAGE_2_CMSG(&CMSG, m);
|
|
if ((FileTransfer || FileReceive) &&
|
|
(CMSG.Command == CAPI_DATA_B3) && (CMSG.Info == 0) &&
|
|
(CMSG.Reason == 0) && (CMSG.Reason_B3 == 0)) {
|
|
|
|
return;
|
|
}
|
|
puts(Message);
|
|
if (CMSG.Info != 0) {
|
|
printf("Info 0x%04X: %s\n",CMSG.Info,Decode_Info(CMSG.Info));
|
|
fprintf(ProtocolFile,"Info 0x%04X: %s\n",CMSG.Info,Decode_Info(CMSG.Info));
|
|
}
|
|
if (CMSG.Reason != 0) {
|
|
printf("Reason 0x%04X: %s\n",CMSG.Reason,Decode_Info(CMSG.Reason));
|
|
fprintf(ProtocolFile,"Reason 0x%04X: %s\n",CMSG.Reason,Decode_Info(CMSG.Reason));
|
|
}
|
|
if (CMSG.Reason_B3 != 0) {
|
|
printf("Reason_B3 0x%04X: %s\n",CMSG.Reason_B3,Decode_Info(CMSG.Reason_B3));
|
|
fprintf(ProtocolFile,"Reason_B3 0x%04X: %s\n",CMSG.Reason_B3,Decode_Info(CMSG.Reason_B3));
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
* Prot_Init: Initialisation of the protocol
|
|
\*--------------------------------------------------------------------------*/
|
|
int Prot_Init(char *Filename) {
|
|
char *p;
|
|
|
|
strcpy(ProtocolFileName, Filename);
|
|
p = strrchr(ProtocolFileName, '.');
|
|
if (p) *p = '\0';
|
|
strcat(ProtocolFileName, ".prt");
|
|
|
|
if ((ProtocolFile=fopen(ProtocolFileName, "w"))==NULL) {
|
|
printf("Can't open protocol-file !!\n");
|
|
return FALSE;
|
|
}
|
|
CAPI_PROTOCOL_INIT(CAPI_PROT_BUF, CAPI_PROT_HANDLE);
|
|
return TRUE;
|
|
}
|
|
#endif
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
* The following _h functions are 'h'igh level functions for the ones
|
|
* implemented in CONNECT.C . The _h functions perform some parameter tests
|
|
* that would cause an assert on the low-level functions.
|
|
\*--------------------------------------------------------------------------*/
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
* Connect_h: Asks for a number to call then executes 'Connect'
|
|
\*--------------------------------------------------------------------------*/
|
|
unsigned Connect_h(ConnectionID *Connection,
|
|
char *CallingPartyNumber,
|
|
unsigned long Service,
|
|
unsigned short B1Protocol,
|
|
unsigned short B2Protocol,
|
|
unsigned short B3Protocol,
|
|
unsigned char __far *B3Configuration) {
|
|
|
|
if (*Connection != INVALID_CONNECTION_ID) {
|
|
printf("Connect_h: Connection is already in use\n");
|
|
return 0xFFFF;
|
|
}
|
|
|
|
printf("Enter Number to call: ");
|
|
fflush (stdout);
|
|
gets(CalledPartyNumberArr);
|
|
|
|
return Connect(Connection,
|
|
CalledPartyNumberArr,
|
|
CallingPartyNumber,
|
|
Service,
|
|
B1Protocol,
|
|
B2Protocol,
|
|
B3Protocol,
|
|
B3Configuration);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
* Disconnect_h: high level Disconnect
|
|
\*--------------------------------------------------------------------------*/
|
|
unsigned Disconnect_h(ConnectionID Connection) {
|
|
|
|
int index;
|
|
ConnectionState State;
|
|
|
|
if (Connection == INVALID_CONNECTION_ID) {
|
|
printf("Disconnect_h: ConnectionID is invalid\n");
|
|
return 0xFFFF;
|
|
}
|
|
State = GetState(Connection);
|
|
if ((State == Disconnected) || (State == D_DisconnectPending)) {
|
|
index = GetSlot(Connection);
|
|
printf("Disconnect_h: slot %d ID %d is disconnected\n",index, Connection);
|
|
return 0xFFFF;
|
|
}
|
|
return Disconnect(Connection);
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
* SendData_h: high level SendData
|
|
\*--------------------------------------------------------------------------*/
|
|
void InitQueue(void) {
|
|
unsigned x;
|
|
|
|
for (x=0; x<QueueSize; x++) {
|
|
Queue.Element[x].SENT = FALSE;
|
|
}
|
|
Queue.Head = 0;
|
|
Queue.Tail = 0;
|
|
Queue.Fill = 0;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
* AnswerCall_h: high level AnswerCall
|
|
\*--------------------------------------------------------------------------*/
|
|
void TransferData(int index) {
|
|
MESSAGE_EXCHANGE_ERROR error;
|
|
unsigned t;
|
|
|
|
if (Queue.Fill > 0) {
|
|
t = Queue.Tail;
|
|
do {
|
|
if (Queue.Element[t].SENT == FALSE) {
|
|
error = SendData(index,
|
|
(void __far *)Queue.Element[t].DATA,
|
|
Queue.Element[t].DATA_LENGTH,
|
|
(unsigned short)t);
|
|
|
|
if (error != 0) {
|
|
printf("Error transfering data: 0x%04X !!!\n",error);
|
|
break;
|
|
}
|
|
Queue.Element[t].SENT = TRUE;
|
|
}
|
|
if (++t >= QueueSize) t = 0;
|
|
} while (t != Queue.Head);
|
|
}
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
* SendFax: Asks for a filename and sends it as a fax
|
|
\*--------------------------------------------------------------------------*/
|
|
unsigned SendFax(int SlotNr) {
|
|
|
|
char Filename[80];
|
|
unsigned count;
|
|
int FAX_Format;
|
|
B3_PROTO_FAXG3 B3conf;
|
|
|
|
printf("This demo program can send ASCII and FAX-format files (.sff). Filenames\n");
|
|
printf("with extensions other than .sff will be interpreted as ASCII-files.\n");
|
|
printf("The name of the demo-fax-file is \"TESTFAX.SFF\".\n");
|
|
printf("Enter Filename: ");
|
|
fflush (stdout);
|
|
gets(Filename);
|
|
FAX_Format = strstr( Filename, ".sff" ) ? FAX_SFF_FORMAT : FAX_ASCII_FORMAT;
|
|
|
|
File = fopen(Filename, "rb");
|
|
if (! File) {
|
|
# ifdef DEBUG
|
|
CAPI_PROTOCOL_TEXT("***** could not open file: \"%s\" *****\n",Filename);
|
|
# endif
|
|
return 1;
|
|
}
|
|
# ifdef DEBUG
|
|
CAPI_PROTOCOL_TEXT("***** opening file: \"%s\" *****\n",Filename);
|
|
# endif
|
|
|
|
InitQueue();
|
|
|
|
SetupB3Config( &B3conf, FAX_Format);
|
|
Connect_h(&Slot[SlotNr],
|
|
CallingPartyNumber,
|
|
SPEECH,
|
|
B1PROTOCOL,
|
|
B2PROTOCOL,
|
|
B3PROTOCOL,
|
|
(_cstruct)&B3conf);
|
|
|
|
do {
|
|
Handle_CAPI_Msg();
|
|
if (Slot[SlotNr] == INVALID_CONNECTION_ID) {
|
|
# ifdef DEBUG
|
|
CAPI_PROTOCOL_TEXT("***** disconnected, please try again *****\n\n");
|
|
# endif
|
|
fclose(File);
|
|
return 2;
|
|
}
|
|
} while (GetState(Slot[SlotNr]) != Connected);
|
|
|
|
|
|
FileTransfer = TRUE;
|
|
|
|
# ifdef DEBUG
|
|
CAPI_PROTOCOL_TEXT("***** Starting datatransfer, press any key to stop *****\n");
|
|
CAPI_PROTOCOL_TEXT("***** there is no protocol output to the screen during transfer *****\n");
|
|
# endif
|
|
do {
|
|
|
|
if ((! feof(File)) && (Queue.Fill < 7)) { /*----- max. 7 outstanding blocks supported by CAPI -----*/
|
|
count = fread(&(Queue.Element[Queue.Head].DATA[0]), 1, SendBlockSize, File);
|
|
if (count > 0) {
|
|
Queue.Element[Queue.Head].DATA_LENGTH = (unsigned short)count;
|
|
if (++Queue.Head >= QueueSize) Queue.Head = 0;
|
|
Queue.Fill++;
|
|
}
|
|
}
|
|
if (GetState(Slot[SlotNr]) != Connected) {
|
|
# ifdef DEBUG
|
|
CAPI_PROTOCOL_TEXT("***** connection broken *****\n");
|
|
# endif
|
|
break;
|
|
}
|
|
if (kbhit()) {
|
|
getch();
|
|
# ifdef DEBUG
|
|
CAPI_PROTOCOL_TEXT("***** interrupted by user *****\n");
|
|
# endif
|
|
break;
|
|
}
|
|
TransferData(SlotNr);
|
|
Handle_CAPI_Msg();
|
|
|
|
} while (!feof(File));
|
|
|
|
Disconnect_h(Slot[SlotNr]);
|
|
while ((Slot[SlotNr] != INVALID_CONNECTION_ID) && (GetState(Slot[SlotNr]) != Disconnected)) {
|
|
Handle_CAPI_Msg();
|
|
# if defined (TARGET_NW)
|
|
delay(50); // the netware NLM has to be cooperative
|
|
# endif
|
|
if (kbhit()) {
|
|
getch();
|
|
# ifdef DEBUG
|
|
CAPI_PROTOCOL_TEXT("***** interrupted by user *****\n");
|
|
# endif
|
|
return 4;
|
|
}
|
|
|
|
};
|
|
|
|
FileTransfer = FALSE;
|
|
# ifdef DEBUG
|
|
CAPI_PROTOCOL_TEXT("***** End of transfer *****\n");
|
|
# endif
|
|
fclose(File);
|
|
return 0;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
* ReceiveFax: Waits for incoming data and stores it to disk
|
|
\*--------------------------------------------------------------------------*/
|
|
unsigned ReceiveFax(int SlotNr) {
|
|
|
|
char Filename[80];
|
|
char *p;
|
|
|
|
printf("The default extension for the FAX-data is .sff\n");
|
|
printf("Enter Filename where incoming data shall be saved: ");
|
|
fflush (stdout);
|
|
gets(Filename);
|
|
|
|
p = strchr(Filename, '.');
|
|
if (p) *p = '\0';
|
|
strcat(Filename, ".sff");
|
|
|
|
|
|
File = fopen(Filename, "wb");
|
|
if (! File) {
|
|
# ifdef DEBUG
|
|
CAPI_PROTOCOL_TEXT("***** could not open file: \"%s\" *****\n",Filename);
|
|
# endif
|
|
return 3;
|
|
}
|
|
printf("opening file: \"%s\"\n\n",Filename);
|
|
|
|
InitQueue();
|
|
|
|
FileReceive = TRUE;
|
|
|
|
# ifdef DEBUG
|
|
CAPI_PROTOCOL_TEXT("***** Waiting for data , press any key to stop *****\n");
|
|
CAPI_PROTOCOL_TEXT("***** there is no protocol output to the screen during transfer *****\n");
|
|
# endif
|
|
|
|
Listen(0x1FFF03FF);
|
|
|
|
while (GetState(Slot[SlotNr]) != Connected) {
|
|
Handle_CAPI_Msg();
|
|
if (kbhit()) {
|
|
# if defined (TARGET_NW)
|
|
delay(50); // the netware NLM has to be cooperative
|
|
# endif
|
|
getch();
|
|
# ifdef DEBUG
|
|
CAPI_PROTOCOL_TEXT("***** interrupted by user *****\n");
|
|
# endif
|
|
fclose(File);
|
|
FileReceive = FALSE;
|
|
return 0;
|
|
}
|
|
}
|
|
while (GetState(Slot[SlotNr]) != INVAL_STATE) {
|
|
Handle_CAPI_Msg();
|
|
if (kbhit()) {
|
|
# if defined (TARGET_NW)
|
|
delay(50); // the netware NLM has to be cooperative
|
|
# endif
|
|
getch();
|
|
# ifdef DEBUG
|
|
CAPI_PROTOCOL_TEXT("***** interrupted by user *****\n");
|
|
# endif
|
|
FileReceive = FALSE;
|
|
fclose(File);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
FileReceive = FALSE;
|
|
|
|
# ifdef DEBUG
|
|
CAPI_PROTOCOL_TEXT("***** End of FAX-receive *****\n");
|
|
# endif
|
|
|
|
fclose(File);
|
|
return 0;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
* HandleKeyStroke: Checks the keyboard
|
|
\*--------------------------------------------------------------------------*/
|
|
int HandleKeyStroke(void) {
|
|
int i;
|
|
|
|
if (kbhit()) {
|
|
i = Press_Key();
|
|
switch (i) {
|
|
case 27: { /*----- ESCAPE -----*/
|
|
printf("Exit program ? y/n ");
|
|
fflush (stdout);
|
|
i = Press_Key();
|
|
if ((i == 'y') || (i =='Y')) {
|
|
puts("Y");
|
|
return FALSE;
|
|
}
|
|
puts("N");
|
|
return TRUE;
|
|
}
|
|
case 's':
|
|
case 'S':
|
|
SendFax(0);
|
|
break;
|
|
case 'r':
|
|
case 'R':
|
|
ReceiveFax(0);
|
|
break;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
* Interact: main loop, checks keystrokes and CAPI-messages
|
|
\*--------------------------------------------------------------------------*/
|
|
void Interact(void) {
|
|
int numController;
|
|
int BChannels, Contr;
|
|
|
|
|
|
numController = GetNumController ();
|
|
BChannels = 0;
|
|
for (Contr=1; Contr<=numController; Contr++)
|
|
BChannels += GetNumOfSupportedBChannels(Contr);
|
|
|
|
printf("Detected %i controllers with %i B-channels overall.\n\n",
|
|
numController, BChannels);
|
|
|
|
puts("'s'+'S' Send fax");
|
|
puts("'r'+'R' Receive fax");
|
|
|
|
do {
|
|
# if defined (TARGET_NW)
|
|
delay(50); // the netware NLM has to be cooperative
|
|
# endif
|
|
Handle_CAPI_Msg();
|
|
} while (HandleKeyStroke());
|
|
|
|
puts("\nProgram terminated\n");
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
* Hangup: Disconnect both channels
|
|
\*--------------------------------------------------------------------------*/
|
|
void Hangup(void) {
|
|
int i;
|
|
|
|
|
|
if ((Slot[0] != INVALID_CONNECTION_ID) &&
|
|
(GetState(Slot[0]) != Disconnected) &&
|
|
(GetState(Slot[0]) != D_DisconnectPending))
|
|
Disconnect(Slot[0]);
|
|
|
|
if ((Slot[1] != INVALID_CONNECTION_ID) &&
|
|
(GetState(Slot[1]) != Disconnected) &&
|
|
(GetState(Slot[1]) != D_DisconnectPending))
|
|
Disconnect(Slot[1]);
|
|
|
|
do {
|
|
Handle_CAPI_Msg();
|
|
# if defined (TARGET_NW)
|
|
delay(50); // the netware NLM has to be cooperative
|
|
# endif
|
|
if (kbhit()) {
|
|
while (kbhit()) {
|
|
getch();
|
|
}
|
|
printf("Exit program ? y/n ");
|
|
fflush (stdout);
|
|
i = Press_Key();
|
|
if ((i == 'y') || (i =='Y')) {
|
|
puts("Y");
|
|
return;
|
|
}
|
|
puts("N");
|
|
}
|
|
}
|
|
while ((Slot[0] != INVALID_CONNECTION_ID) || (Slot[1] != INVALID_CONNECTION_ID));
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
* ctrlchandler: exits on CTRL-C and CTRL-BREAK
|
|
\*--------------------------------------------------------------------------*/
|
|
void ctrlchandler(int sig)
|
|
{
|
|
signal( SIGINT, ctrlchandler );
|
|
exit(0);
|
|
sig = 0; /*----- suppress warning -----*/
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------*\
|
|
* main: Init & exit functions
|
|
\*--------------------------------------------------------------------------*/
|
|
#ifdef DEBUG
|
|
int main(int ac, char *av[]) {
|
|
#else
|
|
int main(void) {
|
|
#endif
|
|
|
|
Slot[0] = INVALID_CONNECTION_ID;
|
|
Slot[1] = INVALID_CONNECTION_ID;
|
|
|
|
if (! RegisterCAPI ()) return 1;
|
|
atexit (ReleaseCAPI);
|
|
|
|
signal(SIGINT, ctrlchandler);
|
|
|
|
InitConnectionIDHandling ();
|
|
|
|
|
|
#ifdef DEBUG
|
|
if (! Prot_Init(av[ac-1])) return 2;
|
|
#endif
|
|
|
|
#ifdef __linux__
|
|
init_tty();
|
|
atexit (restore_tty);
|
|
#endif
|
|
|
|
Interact();
|
|
|
|
Hangup();
|
|
|
|
#ifdef DEBUG
|
|
fclose(ProtocolFile);
|
|
#endif
|
|
return 0;
|
|
}
|