2247 lines
81 KiB
C
2247 lines
81 KiB
C
/*
|
||
* universal multiplayer library level 0 implementation file
|
||
* transport layer: modem PC-windows 95
|
||
*/
|
||
|
||
/*
|
||
* Author: Christophe Roguet
|
||
*
|
||
* Modification Date: 09/07/96
|
||
*
|
||
* The modem layer uses most of the functionalities of the serial layer.
|
||
* The differences reside in this file and concern the processes of connection and deconnection.
|
||
*
|
||
* lots of restrictions:
|
||
* - the modem uses a special serial channel (the last one) instead of the channel associated
|
||
* to its COM port
|
||
* - only one call at a time is allowed (gets confused if many applications try to connect ...)
|
||
* - parts of the code are written as if many modem channels could coexist, for an eventual future
|
||
* version
|
||
*
|
||
* REMARKS:
|
||
*
|
||
* - in order for the modem events to be properly dispatched,
|
||
* the application must dispatch window messages
|
||
* - to avoid problems, the vL0PCWin95ModemExitTAPI() function must be called whenever the
|
||
* application is left
|
||
* - thread problem ??? the thread in which lineInitialize() is called is the
|
||
* thread that receives the callback ... it must pump windows messages ...
|
||
*
|
||
*/
|
||
|
||
#include "warnings.h"
|
||
|
||
#define TAPI_CURRENT_VERSION 0x00010004
|
||
|
||
#include <tapi.h>
|
||
#include <mcx.h>
|
||
|
||
#include <NET\Netdebug.h>
|
||
|
||
#ifdef NET_USE_DEBUG
|
||
#include <stdio.h>
|
||
#endif
|
||
/*
|
||
* we need this one to fill the interface structure
|
||
* with pointers to the correct functions
|
||
*/
|
||
|
||
#include "PrivL0modem.h"
|
||
#include "PrivNetDef.h"
|
||
#include "L0GlDef.h"
|
||
#include "NetMemCo.h"
|
||
|
||
|
||
#define MODEM_WINDOW 20
|
||
#define MODEM_RATE XXXXX
|
||
#define MODEM_TIMEOUT 1000
|
||
#define MODEM_LINKNUMBER 100/*2*MODEM_WINDOW*/
|
||
|
||
/* typedefs necessary for parameters to lineSetDevConfig for Unimodem ... */
|
||
/* (refer to "comm/datamodem" */
|
||
|
||
/* Device setting information*/
|
||
typedef struct tagDEVCFGDR {
|
||
DWORD dwSize;
|
||
DWORD dwVersion;
|
||
WORD fwOptions;
|
||
WORD wWaitBong;
|
||
} DEVCFGHDR;
|
||
|
||
typedef struct tagDEVCFG {
|
||
DEVCFGHDR dfgHdr;
|
||
COMMCONFIG commconfig;
|
||
} DEVCFG, *PDEVCFG, FAR* LPDEVCFG;
|
||
|
||
|
||
|
||
/* local functions declaration */
|
||
|
||
void L0PCWin95ModemDoLineCallState(DWORD, DWORD, DWORD, DWORD, DWORD, DWORD);
|
||
void L0PCWin95ModemDoLineClose(DWORD, DWORD, DWORD, DWORD, DWORD, DWORD);
|
||
void L0PCWin95ModemDoLineDevState(DWORD, DWORD, DWORD, DWORD, DWORD, DWORD);
|
||
void L0PCWin95ModemDoLineReply(DWORD, DWORD, DWORD, DWORD, DWORD, DWORD);
|
||
void L0PCWin95ModemDoLineCreate(DWORD, DWORD, DWORD, DWORD, DWORD, DWORD);
|
||
|
||
|
||
void vL0PCWin95ModemExitTAPI();
|
||
void vL0PCWin95ModemConnect();
|
||
void vL0PCWin95ModemDisconnect();
|
||
void vL0PCWin95ModemAnswer(HCALL);
|
||
void vL0PCWin95ModemRelease(HCALL);
|
||
void vL0PCWin95ModemCloseChannel(tduwNetChannel);
|
||
void vL0PCWin95ModemCloseProtocol(void);
|
||
|
||
/* array of descriptors to access a physical channel. */
|
||
/* problem there: should be the static array defined in level0_Serial_PCWin95.cpp ... */
|
||
#define C_uw_Net_L0PCWin95Serial_PortNumber ((unsigned short)5)
|
||
|
||
#undef extern /* what is this define for ???? */
|
||
extern tdstL0PCWin95SerialChannel gs_a_stL0PCWin95SerialChannels[C_uw_Net_L0PCWin95Serial_PortNumber];
|
||
extern long lSerialChannelsOnceInitialized;
|
||
|
||
/* the last serial channel is dedicated to the modem */
|
||
|
||
#define C_ModemSpecialChannel (C_uw_Net_L0PCWin95Serial_PortNumber-1)
|
||
|
||
/* global variables */
|
||
|
||
static HINSTANCE gs_hInstance; /* application instance handle */
|
||
static tdfnvModemCallback gs_tdfnvModemCallback; /* pointer to the application callback function */
|
||
|
||
static HLINEAPP gs_hLineApp; /* TAPI application ID */
|
||
static DWORD gs_dwNumDevs; /* number of available line devices */
|
||
static HLINE gs_hLine; /* line ID */
|
||
static HCALL gs_hCall; /* call ID */
|
||
static LINECALLPARAMS *lpCallParams; /* parameters for the call; could be local ??? */
|
||
static gs_cModemAnswerMode; /* boolean: upon reception of incoming call, reject it or accept it ? */
|
||
static HANDLE gs_hWaitForRelease; /* synchronization object for call deallocation */
|
||
static COMMCONFIG *gs_pstCommConfig; /* modem configuration */
|
||
static unsigned long gs_ulCommConfigSize;
|
||
static DWORD gs_dwInitialiserThreadId; /* Id of the thread that initialized the protocol */
|
||
|
||
|
||
static char gs_bL0PCWin95ModemInitState;
|
||
|
||
static unsigned long gs_ulL0PCWin95ModemBaudRate;
|
||
|
||
/*******************************************************************/
|
||
|
||
#ifdef NET_USE_DEBUG
|
||
|
||
void vL0PCWin95ModemDisplayModemOptions(DWORD ModemOptions)
|
||
|
||
{
|
||
char acString[200];
|
||
int pos;
|
||
|
||
pos=0;
|
||
pos+=sprintf(acString, "( ");
|
||
|
||
if(ModemOptions & MDM_BLIND_DIAL)
|
||
pos+=sprintf(acString+pos, "BLIND_DIAL ");
|
||
if(ModemOptions & MDM_CCITT_OVERRIDE)
|
||
pos+=sprintf(acString+pos, "CCITT_OVERRIDE ");
|
||
if(ModemOptions & MDM_CELLULAR)
|
||
pos+=sprintf(acString+pos, "CELLULAR ");
|
||
if(ModemOptions & MDM_COMPRESSION)
|
||
pos+=sprintf(acString+pos, "COMPRESSION ");
|
||
if(ModemOptions & MDM_ERROR_CONTROL)
|
||
pos+=sprintf(acString+pos, "ERROR_CONTROL ");
|
||
if(ModemOptions & MDM_FLOWCONTROL_HARD)
|
||
pos+=sprintf(acString+pos, "FLOWCONTROL_HARD ");
|
||
if(ModemOptions & MDM_FLOWCONTROL_SOFT)
|
||
pos+=sprintf(acString+pos, "FLOWCONTROL_SOFT ");
|
||
if(ModemOptions & MDM_FORCED_EC)
|
||
pos+=sprintf(acString+pos, "FORCED_EC ");
|
||
if(ModemOptions & MDM_SPEED_ADJUST)
|
||
pos+=sprintf(acString+pos, "SPEED_ADJUST ");
|
||
if(ModemOptions & MDM_TONE_DIAL)
|
||
pos+=sprintf(acString+pos, "TONE_DIAL ");
|
||
if(ModemOptions & MDM_V23_OVERRIDE)
|
||
pos+=sprintf(acString+pos, "V23_OVERRIDE ");
|
||
|
||
pos+=sprintf(acString+pos, ")");
|
||
|
||
vDebugS(Net_C_Debug_Modem, acString);
|
||
}
|
||
|
||
void vL0PCWin95ModemDisplayModemSettings(MODEMSETTINGS *pModemSettings)
|
||
|
||
{
|
||
vDebugFormat(Net_C_Debug_Modem, "dwActualSize:\t%d", pModemSettings->dwActualSize);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwRequiredSize:\t%d", pModemSettings->dwRequiredSize);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwDevSpecificSize:\t%d", pModemSettings->dwDevSpecificSize);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwCallSetupFailTimer:\t%d", pModemSettings->dwCallSetupFailTimer);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwInactivityTimeout:\t%d", pModemSettings->dwInactivityTimeout);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwSpeakerVolume:\t0x%08x", pModemSettings->dwSpeakerVolume);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwSpeakerMode:\t0x%08x", pModemSettings->dwSpeakerMode);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwPreferredModemOptions:\t0x%08x", pModemSettings->dwPreferredModemOptions);
|
||
vL0PCWin95ModemDisplayModemOptions(pModemSettings->dwPreferredModemOptions);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwNegotiatedModemOptions:\t0x%08x", pModemSettings->dwNegotiatedModemOptions);
|
||
vL0PCWin95ModemDisplayModemOptions(pModemSettings->dwNegotiatedModemOptions);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwNegotiatedDCERate:\t%d", pModemSettings->dwNegotiatedDCERate);
|
||
}
|
||
|
||
#endif /* NET_USE_DEBUG */
|
||
|
||
/*******************************************************************/
|
||
|
||
#ifdef NET_USE_DEBUG
|
||
|
||
void vL0PCWin95ModemDisplayModemDevCaps(MODEMDEVCAPS *pModemDevCaps)
|
||
|
||
{
|
||
|
||
#define STRING_MAX_SIZE 80
|
||
|
||
char string[STRING_MAX_SIZE];
|
||
|
||
vDebugFormat(Net_C_Debug_Modem, "dwActualSize:\t%d", pModemDevCaps->dwActualSize);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwRequiredSize:\t%d", pModemDevCaps->dwRequiredSize);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwDevSpecificOffset:\t%d", pModemDevCaps->dwDevSpecificOffset);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwDevSpecificSize:\t%d", pModemDevCaps->dwDevSpecificSize);
|
||
|
||
vDebugFormat(Net_C_Debug_Modem, "dwModemProviderVersion:\t%d", pModemDevCaps->dwModemProviderVersion);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwModemManufacturerOffset:\t%d", pModemDevCaps->dwModemManufacturerOffset);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwModemManufacturerSize:\t%d", pModemDevCaps->dwModemManufacturerSize);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwModemModelOffset:\t%d", pModemDevCaps->dwModemModelOffset);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwModemModelSize:\t%d", pModemDevCaps->dwModemModelSize);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwModemVersionOffset:\t%d", pModemDevCaps->dwModemVersionOffset);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwModemVersionSize:\t%d", pModemDevCaps->dwModemVersionSize);
|
||
|
||
vDebugFormat(Net_C_Debug_Modem, "dwDialOptions:\t0x%08x", pModemDevCaps->dwDialOptions);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwCallSetupFailTimer:\t%d", pModemDevCaps->dwCallSetupFailTimer);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwInactivityTimeout:\t%d", pModemDevCaps->dwInactivityTimeout);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwSpeakerVolume:\t0x%08x", pModemDevCaps->dwSpeakerVolume);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwSpeakerMode:\t0x%08x", pModemDevCaps->dwSpeakerMode);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwModemOptions:\t0x%08x", pModemDevCaps->dwModemOptions);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwMaxDTERate:\t%d", pModemDevCaps->dwMaxDTERate);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwMaxDCERate:\t%d", pModemDevCaps->dwMaxDCERate);
|
||
|
||
if(pModemDevCaps->dwModemManufacturerOffset!=0) {
|
||
if(pModemDevCaps->dwModemManufacturerSize>=STRING_MAX_SIZE) {
|
||
memcpy(string, ((char *)pModemDevCaps)+pModemDevCaps->dwModemManufacturerOffset,
|
||
STRING_MAX_SIZE-1);
|
||
string[STRING_MAX_SIZE-1]='\0';
|
||
} else {
|
||
memcpy(string, ((char *)pModemDevCaps)+pModemDevCaps->dwModemManufacturerOffset,
|
||
pModemDevCaps->dwModemManufacturerSize);
|
||
string[pModemDevCaps->dwModemManufacturerSize]='\0';
|
||
}
|
||
|
||
vDebugFormat(Net_C_Debug_Modem, "ModemManufacturer: %s", string);
|
||
}
|
||
|
||
if(pModemDevCaps->dwModemModelOffset!=0) {
|
||
if(pModemDevCaps->dwModemModelSize>=STRING_MAX_SIZE) {
|
||
memcpy(string, ((char *)pModemDevCaps)+pModemDevCaps->dwModemModelOffset,
|
||
STRING_MAX_SIZE-1);
|
||
string[STRING_MAX_SIZE-1]='\0';
|
||
} else {
|
||
memcpy(string, ((char *)pModemDevCaps)+pModemDevCaps->dwModemModelOffset,
|
||
pModemDevCaps->dwModemModelSize);
|
||
string[pModemDevCaps->dwModemModelSize]='\0';
|
||
}
|
||
|
||
vDebugFormat(Net_C_Debug_Modem, "ModemModel: %s", string);
|
||
}
|
||
|
||
if(pModemDevCaps->dwModemVersionOffset!=0) {
|
||
if(pModemDevCaps->dwModemVersionSize>=STRING_MAX_SIZE) {
|
||
memcpy(string, ((char *)pModemDevCaps)+pModemDevCaps->dwModemVersionOffset,
|
||
STRING_MAX_SIZE-1);
|
||
string[STRING_MAX_SIZE-1]='\0';
|
||
} else {
|
||
memcpy(string, ((char *)pModemDevCaps)+pModemDevCaps->dwModemVersionOffset,
|
||
pModemDevCaps->dwModemVersionSize);
|
||
string[pModemDevCaps->dwModemVersionSize]='\0';
|
||
}
|
||
|
||
vDebugFormat(Net_C_Debug_Modem, "ModemVersion: %s", string);
|
||
}
|
||
}
|
||
|
||
#endif /* NET_USE_DEBUG */
|
||
|
||
/*******************************************************************/
|
||
|
||
#ifdef NET_USE_DEBUG
|
||
|
||
void vL0PCWin95ModemDisplayCommTimeouts(LPCOMMTIMEOUTS pcto)
|
||
|
||
{
|
||
vDebugFormat(Net_C_Debug_Modem, "ReadIntervalTimeout: %d", pcto->ReadIntervalTimeout);
|
||
vDebugFormat(Net_C_Debug_Modem, "ReadTotalTimeoutMultiplier: %d", pcto->ReadTotalTimeoutMultiplier);
|
||
vDebugFormat(Net_C_Debug_Modem, "ReadTotalTimeoutConstant: %d", pcto->ReadTotalTimeoutConstant);
|
||
vDebugFormat(Net_C_Debug_Modem, "WriteTotalTimeoutMultiplier: %d", pcto->WriteTotalTimeoutMultiplier);
|
||
vDebugFormat(Net_C_Debug_Modem, "WriteTotalTimeoutConstant: %d", pcto->WriteTotalTimeoutConstant);
|
||
}
|
||
|
||
#endif /* NET_USE_DEBUG */
|
||
|
||
/*******************************************************************/
|
||
|
||
void vL0PCWin95ModemInitializeCommConfig(COMMCONFIG *pCommConfig)
|
||
|
||
{
|
||
MODEMSETTINGS *pModemSettings;
|
||
DCB *pDcb;
|
||
|
||
/* initialize the COM port part of the commconfig */
|
||
|
||
pDcb=&pCommConfig->dcb;
|
||
|
||
pDcb->BaudRate= gs_ulL0PCWin95ModemBaudRate;
|
||
|
||
pDcb->fBinary = TRUE; /* not text transfer */
|
||
|
||
pDcb->ByteSize = 8; /* 8 bit chars */
|
||
pDcb->fParity = FALSE; /* no parity checking */
|
||
pDcb->Parity = NOPARITY; /* no parity checking (redundant ?) */
|
||
pDcb->StopBits = ONESTOPBIT;
|
||
|
||
pDcb->fErrorChar = FALSE; /* do not replace bad chars */
|
||
pDcb->fAbortOnError = FALSE; /* do not replace bad chars */
|
||
|
||
pDcb->fOutxCtsFlow = TRUE; /* hardware flow control */
|
||
pDcb->fOutxDsrFlow = FALSE; /* hardware flow control */
|
||
pDcb->fDtrControl = DTR_CONTROL_ENABLE; /* hardware flow control */
|
||
pDcb->fDsrSensitivity = FALSE; /* hardware flow control */
|
||
pDcb->fRtsControl = RTS_CONTROL_HANDSHAKE; /* hardware flow control */
|
||
|
||
|
||
/* no software flow control */
|
||
|
||
pDcb->fOutX = FALSE;
|
||
pDcb->fInX = FALSE;
|
||
|
||
pDcb->fNull = FALSE;
|
||
|
||
/* initialize the modem part of the commconfig */
|
||
|
||
pModemSettings=(MODEMSETTINGS *)pCommConfig->wcProviderData;
|
||
|
||
#ifdef NET_USE_DEBUG
|
||
vL0PCWin95ModemDisplayModemSettings(pModemSettings);
|
||
#endif /* NET_USE_DEBUG */
|
||
|
||
pModemSettings->dwCallSetupFailTimer=35; /* thirty five seconds */
|
||
pModemSettings->dwInactivityTimeout=MAXDWORD; /* can remain inactive 'forever' ?*/
|
||
pModemSettings->dwSpeakerVolume=MDMVOL_MEDIUM;
|
||
pModemSettings->dwSpeakerMode=MDMSPKR_CALLSETUP;
|
||
pModemSettings->dwPreferredModemOptions|=
|
||
MDM_FLOWCONTROL_HARD /* harware flow control */
|
||
/* | MDM_COMPRESSION /* hardware data compression */
|
||
| MDM_BLIND_DIAL /* do not wait for dial tone */
|
||
/* | MDM_TONE_DIAL /* use tone dialing */
|
||
;
|
||
pModemSettings->dwPreferredModemOptions&=
|
||
~MDM_COMPRESSION /* no compression */
|
||
& ~MDM_FLOWCONTROL_SOFT; /* no software flow control */
|
||
;
|
||
}
|
||
|
||
/*******************************************************************/
|
||
|
||
void vL0PCWin95ModemInitializeCommTimeouts(LPCOMMTIMEOUTS pcto)
|
||
|
||
{
|
||
/* timeouts should be tailored to baud rate and/or vNetEngine() call frequency */
|
||
|
||
pcto->ReadIntervalTimeout = 0; /* no timeout */
|
||
pcto->ReadTotalTimeoutMultiplier = 0 ;
|
||
pcto->ReadTotalTimeoutConstant = 200/*MAXDWORD*/ ;
|
||
pcto->WriteTotalTimeoutMultiplier = 0 ;
|
||
pcto->WriteTotalTimeoutConstant = MAXDWORD;
|
||
}
|
||
|
||
/*****************************************************************************
|
||
*
|
||
* Description: uwL0PCWin95ModemStartChannelScan
|
||
*
|
||
* returns the identification number of the first channel for the protocol
|
||
*
|
||
*****************************************************************************
|
||
*
|
||
* Input: none
|
||
*
|
||
* Output: identification of the channel
|
||
*
|
||
*****************************************************************************
|
||
* Creation Date: April 15, 1996 Author: Christophe Roguet
|
||
*****************************************************************************
|
||
*
|
||
* Modification log:
|
||
*
|
||
* Date: Author:
|
||
*
|
||
****************************************************************************/
|
||
tduwNetChannel uwL0PCWin95ModemStartChannelScan(void)
|
||
{
|
||
tduwNetChannel uwCurrentChannel;
|
||
|
||
/* scan the array of channel definitions */
|
||
for (uwCurrentChannel = 0; uwCurrentChannel < C_uw_Net_L0PCWin95Serial_PortNumber; uwCurrentChannel ++)
|
||
/* if the slot is used, and can transmit data to another individual player */
|
||
if
|
||
(
|
||
gs_a_stL0PCWin95SerialChannels[uwCurrentChannel].ubf1IsSlotInUse
|
||
&& gs_a_stL0PCWin95SerialChannels[uwCurrentChannel].ubf1IsSlotForModem
|
||
&& gs_a_stL0PCWin95SerialChannels[uwCurrentChannel].ubf1IsSlotConnected
|
||
)
|
||
/* return its index value */
|
||
return uwCurrentChannel;
|
||
|
||
/* else no slot is in use */
|
||
return C_uwNetInvalidChannel ;
|
||
}
|
||
|
||
/*****************************************************************************
|
||
*
|
||
* Description: uwL0PCWin95ModemNextChannel
|
||
*
|
||
* returns the identification number of the channel following the last
|
||
*
|
||
*****************************************************************************
|
||
*
|
||
* Input: uwLastScannedChannel, index returned by the previous call
|
||
*
|
||
* Output: identification of the channel following the specified one
|
||
*
|
||
*****************************************************************************
|
||
* Creation Date: April 15, 1996 Author: Christophe Roguet
|
||
*****************************************************************************
|
||
*
|
||
* Modification log:
|
||
*
|
||
* Date: Author:
|
||
*
|
||
****************************************************************************/
|
||
tduwNetChannel uwL0PCWin95ModemNextChannel(tduwNetChannel uwLastScannedChannel)
|
||
{
|
||
tduwNetChannel uwCurrentChannel;
|
||
|
||
/*
|
||
* scan the array of channel definitions, starting with the channel following
|
||
* the last channel returned
|
||
*/
|
||
for
|
||
(
|
||
uwCurrentChannel = (tduwNetChannel)(uwLastScannedChannel + 1);
|
||
uwCurrentChannel < C_uw_Net_L0PCWin95Serial_PortNumber;
|
||
uwCurrentChannel ++
|
||
)
|
||
/* if the slot is used, and can transmit data to another individual player */
|
||
if
|
||
(
|
||
gs_a_stL0PCWin95SerialChannels[uwCurrentChannel].ubf1IsSlotInUse
|
||
&& gs_a_stL0PCWin95SerialChannels[uwCurrentChannel].ubf1IsSlotForModem
|
||
&& gs_a_stL0PCWin95SerialChannels[uwCurrentChannel].ubf1IsSlotConnected
|
||
)
|
||
/* return its index value */
|
||
return uwCurrentChannel;
|
||
|
||
/* else no slot is in use */
|
||
return C_uwNetInvalidChannel;
|
||
}
|
||
|
||
/*****************************************************************************
|
||
*
|
||
* Description: uwL0PCWin95ModemStartBroadcastChannelScan
|
||
*
|
||
* returns the identification number of the first broadcast channel
|
||
* for the protocol
|
||
*
|
||
*****************************************************************************
|
||
*
|
||
* Input: none
|
||
*
|
||
* Output: identification of the channel
|
||
*
|
||
*****************************************************************************
|
||
* Creation Date: April 15, 1996 Author: Christophe Roguet
|
||
*****************************************************************************
|
||
*
|
||
* Modification log:
|
||
*
|
||
* Date: Author:
|
||
*
|
||
****************************************************************************/
|
||
tduwNetChannel uwL0PCWin95ModemStartBroadcastChannelScan(void)
|
||
{
|
||
tduwNetChannel uwCurrentChannel;
|
||
|
||
/* scan the array of channel definitions */
|
||
for (uwCurrentChannel = 0; uwCurrentChannel < C_uw_Net_L0PCWin95Serial_PortNumber; uwCurrentChannel ++)
|
||
/* if the slot is used, and the channel can send broadcast data */
|
||
if
|
||
(
|
||
gs_a_stL0PCWin95SerialChannels[uwCurrentChannel].ubf1IsSlotInUse
|
||
&& gs_a_stL0PCWin95SerialChannels[uwCurrentChannel].ubf1IsSlotForModem
|
||
&& gs_a_stL0PCWin95SerialChannels[uwCurrentChannel].ubf1IsSlotConnected
|
||
&& gs_a_stL0PCWin95SerialChannels[uwCurrentChannel].ubf1IsBroadcast
|
||
)
|
||
/* return its index value */
|
||
return uwCurrentChannel;
|
||
|
||
/* else no slot is in use */
|
||
return C_uwNetInvalidChannel;
|
||
}
|
||
|
||
/*****************************************************************************
|
||
*
|
||
* Description: uwL0PCWin95ModemNextBroadcastChannel
|
||
*
|
||
* returns the identification number of the broadcast channel following
|
||
* the specified one
|
||
*
|
||
*****************************************************************************
|
||
*
|
||
* Input: uwLastScannedChannel, index returned by the previous call
|
||
*
|
||
* Output: identification of the channel following the specified one
|
||
*
|
||
*****************************************************************************
|
||
* Creation Date: April 15, 1996 Author: Christophe Roguet
|
||
*****************************************************************************
|
||
*
|
||
* Modification log:
|
||
*
|
||
* Date: Author:
|
||
*
|
||
****************************************************************************/
|
||
tduwNetChannel uwL0PCWin95ModemNextBroadcastChannel(tduwNetChannel uwLastScannedChannel)
|
||
{
|
||
tduwNetChannel uwCurrentChannel;
|
||
|
||
/*
|
||
* scan the array of channel definitions, starting with the channel following
|
||
* the last channel returned
|
||
*/
|
||
for
|
||
(
|
||
uwCurrentChannel = (tduwNetChannel)(uwLastScannedChannel + 1);
|
||
uwCurrentChannel < C_uw_Net_L0PCWin95Serial_PortNumber;
|
||
uwCurrentChannel ++
|
||
)
|
||
/* if the slot is used, and can transmit broadcast data */
|
||
if
|
||
(
|
||
gs_a_stL0PCWin95SerialChannels[uwCurrentChannel].ubf1IsSlotInUse
|
||
&& gs_a_stL0PCWin95SerialChannels[uwCurrentChannel].ubf1IsSlotForModem
|
||
&& gs_a_stL0PCWin95SerialChannels[uwCurrentChannel].ubf1IsSlotConnected
|
||
&& gs_a_stL0PCWin95SerialChannels[uwCurrentChannel].ubf1IsBroadcast
|
||
)
|
||
/* return its index value */
|
||
return uwCurrentChannel;
|
||
|
||
/* else no slot is in use */
|
||
return C_uwNetInvalidChannel;
|
||
}
|
||
|
||
/*
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Description : void vModemCallback
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input :
|
||
read the SDK ...
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output :
|
||
none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : July 9,96
|
||
Author : Christophe Roguet
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
*/
|
||
void CALLBACK vL0PCWin95ModemCallback(DWORD dwDevice, DWORD dwMsg, DWORD dwCallbackInstance,
|
||
DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
|
||
|
||
{
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "\nModemCallback:\nDev:0x%08x, Msg:%ld, CallbackInstance:%ld, "
|
||
"P1:0x%08x, P2:0x%08x, P3:0x%08x",
|
||
dwDevice, dwMsg, dwCallbackInstance, dwParam1, dwParam2, dwParam3);
|
||
#endif /* NET_USE_DEBUG */
|
||
|
||
/* All we do is dispatch the dwMsg to the correct handler.*/
|
||
switch(dwMsg)
|
||
{
|
||
case LINE_CALLSTATE:
|
||
L0PCWin95ModemDoLineCallState(dwDevice, dwMsg, dwCallbackInstance,
|
||
dwParam1, dwParam2, dwParam3);
|
||
break;
|
||
|
||
case LINE_CLOSE:
|
||
L0PCWin95ModemDoLineClose(dwDevice, dwMsg, dwCallbackInstance,
|
||
dwParam1, dwParam2, dwParam3);
|
||
break;
|
||
|
||
case LINE_LINEDEVSTATE:
|
||
L0PCWin95ModemDoLineDevState(dwDevice, dwMsg, dwCallbackInstance,
|
||
dwParam1, dwParam2, dwParam3);
|
||
break;
|
||
|
||
case LINE_REPLY:
|
||
L0PCWin95ModemDoLineReply(dwDevice, dwMsg, dwCallbackInstance,
|
||
dwParam1, dwParam2, dwParam3);
|
||
break;
|
||
|
||
case LINE_CREATE:
|
||
L0PCWin95ModemDoLineCreate(dwDevice, dwMsg, dwCallbackInstance,
|
||
dwParam1, dwParam2, dwParam3);
|
||
break;
|
||
|
||
default:
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "message non interprete");
|
||
#endif /* NET_USE_DEBUG */
|
||
;
|
||
}
|
||
|
||
}
|
||
|
||
/*************************************************************/
|
||
|
||
void L0PCWin95ModemDoLineCallState(
|
||
DWORD dwDevice, DWORD dwMessage, DWORD dwCallbackInstance,
|
||
DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
|
||
{
|
||
#ifdef NET_USE_DEBUG
|
||
LPSTR pszReasonDisconnected;
|
||
#endif
|
||
|
||
long lDisconnectCause;
|
||
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "LINE_CALLSTATE");
|
||
#endif /* NET_USE_DEBUG */
|
||
|
||
if ((HCALL)dwDevice != gs_hCall)
|
||
{
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "LINE_CALLSTATE: Unknown device ID '0x%lx' (new call ?).\n", dwDevice);
|
||
#endif
|
||
}
|
||
|
||
|
||
/* dwParam3 contains changes to LINECALLPRIVILEGE, if there are any.*/
|
||
switch (dwParam3)
|
||
{
|
||
case 0:
|
||
break; /* no change to call state*/
|
||
|
||
case LINECALLPRIVILEGE_MONITOR:
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "line given monitor privilege");
|
||
#endif /* NET_USE_DEBUG */
|
||
return;
|
||
|
||
/* close line if we are made owner. Shouldn't happen!*/
|
||
case LINECALLPRIVILEGE_OWNER:
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "line given owner privilege");
|
||
#endif /* NET_USE_DEBUG */
|
||
break;
|
||
|
||
default: /* Shouldn't happen! All cases handled.*/
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "Unknown LINECALLPRIVILEGE message: closing");
|
||
#endif /* NET_USE_DEBUG */
|
||
return;
|
||
}
|
||
|
||
/* dwParam1 is the specific CALLSTATE change that is occurring.*/
|
||
switch (dwParam1)
|
||
{
|
||
case LINECALLSTATE_DIALTONE:
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "Dial Tone");
|
||
#endif /* NET_USE_DEBUG */
|
||
if(gs_tdfnvModemCallback)
|
||
gs_tdfnvModemCallback(Netlib_E_mcs_DIALTONE, 0);
|
||
break;
|
||
|
||
case LINECALLSTATE_DIALING:
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "Dialing");
|
||
#endif /* NET_USE_DEBUG */
|
||
if(gs_tdfnvModemCallback)
|
||
gs_tdfnvModemCallback(Netlib_E_mcs_DIALING, 0);
|
||
break;
|
||
|
||
case LINECALLSTATE_PROCEEDING:
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "Proceeding");
|
||
#endif /* NET_USE_DEBUG */
|
||
if(gs_tdfnvModemCallback)
|
||
gs_tdfnvModemCallback(Netlib_E_mcs_PROCEEDING, 0);
|
||
break;
|
||
|
||
case LINECALLSTATE_RINGBACK:
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "RingBack");
|
||
#endif /* NET_USE_DEBUG */
|
||
if(gs_tdfnvModemCallback)
|
||
gs_tdfnvModemCallback(Netlib_E_mcs_RINGBACK, 0);
|
||
break;
|
||
|
||
case LINECALLSTATE_BUSY:
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "Line busy");
|
||
#endif /* NET_USE_DEBUG */
|
||
if(gs_tdfnvModemCallback)
|
||
gs_tdfnvModemCallback(Netlib_E_mcs_BUSY, 0);
|
||
break;
|
||
|
||
case LINECALLSTATE_IDLE:
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "Line idle");
|
||
#endif /* NET_USE_DEBUG */
|
||
if(gs_tdfnvModemCallback)
|
||
gs_tdfnvModemCallback(Netlib_E_mcs_IDLE, 0);
|
||
|
||
/* deallocate the call handle */
|
||
|
||
vL0PCWin95ModemRelease((HCALL)dwDevice);
|
||
break;
|
||
|
||
case LINECALLSTATE_SPECIALINFO:
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "Special Info, probably couldn't dial number");
|
||
#endif /* NET_USE_DEBUG */
|
||
break;
|
||
|
||
case LINECALLSTATE_DISCONNECTED:
|
||
{
|
||
|
||
lDisconnectCause=Netlib_E_mdc_UNKNOWN;
|
||
#ifdef NET_USE_DEBUG
|
||
switch (dwParam2)
|
||
{
|
||
case LINEDISCONNECTMODE_NORMAL:
|
||
pszReasonDisconnected = "Remote Party Disconnected";
|
||
lDisconnectCause=Netlib_E_mdc_NORMAL;
|
||
break;
|
||
|
||
case LINEDISCONNECTMODE_UNKNOWN:
|
||
pszReasonDisconnected = "Disconnected: Unknown reason";
|
||
lDisconnectCause=Netlib_E_mdc_UNKNOWN;
|
||
break;
|
||
|
||
case LINEDISCONNECTMODE_REJECT:
|
||
pszReasonDisconnected = "Remote Party rejected call";
|
||
lDisconnectCause=Netlib_E_mdc_REJECT;
|
||
break;
|
||
|
||
case LINEDISCONNECTMODE_PICKUP:
|
||
pszReasonDisconnected =
|
||
"Disconnected: Local phone picked up";
|
||
lDisconnectCause=Netlib_E_mdc_PICKUP;
|
||
break;
|
||
|
||
case LINEDISCONNECTMODE_FORWARDED:
|
||
pszReasonDisconnected = "Disconnected: Forwarded";
|
||
lDisconnectCause=Netlib_E_mdc_FORWARDED;
|
||
break;
|
||
|
||
case LINEDISCONNECTMODE_BUSY:
|
||
pszReasonDisconnected = "Disconnected: Busy";
|
||
lDisconnectCause=Netlib_E_mdc_BUSY;
|
||
break;
|
||
|
||
case LINEDISCONNECTMODE_NOANSWER:
|
||
pszReasonDisconnected = "Disconnected: No Answer";
|
||
lDisconnectCause=Netlib_E_mdc_NOANSWER;
|
||
break;
|
||
|
||
case LINEDISCONNECTMODE_BADADDRESS:
|
||
pszReasonDisconnected = "Disconnected: Bad Address";
|
||
lDisconnectCause=Netlib_E_mdc_BADADDRESS;
|
||
break;
|
||
|
||
case LINEDISCONNECTMODE_UNREACHABLE:
|
||
pszReasonDisconnected = "Disconnected: Unreachable";
|
||
lDisconnectCause=Netlib_E_mdc_UNREACHABLE;
|
||
break;
|
||
|
||
case LINEDISCONNECTMODE_CONGESTION:
|
||
pszReasonDisconnected = "Disconnected: Congestion";
|
||
lDisconnectCause=Netlib_E_mdc_CONGESTION;
|
||
break;
|
||
|
||
case LINEDISCONNECTMODE_INCOMPATIBLE:
|
||
pszReasonDisconnected = "Disconnected: Incompatible";
|
||
lDisconnectCause=Netlib_E_mdc_INCOMPATIBLE;
|
||
break;
|
||
|
||
case LINEDISCONNECTMODE_UNAVAIL:
|
||
pszReasonDisconnected = "Disconnected: Unavail";
|
||
lDisconnectCause=Netlib_E_mdc_UNAVAIL;
|
||
break;
|
||
|
||
case LINEDISCONNECTMODE_NODIALTONE:
|
||
pszReasonDisconnected = "Disconnected: No Dial Tone";
|
||
lDisconnectCause=Netlib_E_mdc_NODIALTONE;
|
||
break;
|
||
|
||
default:
|
||
pszReasonDisconnected =
|
||
"Disconnected: LINECALLSTATE; Bad Reason";
|
||
lDisconnectCause=-1;
|
||
break;
|
||
|
||
}
|
||
|
||
vDebugFormat(Net_C_Debug_Modem, pszReasonDisconnected);
|
||
|
||
#endif /* NET_USE_DEBUG */
|
||
|
||
if(gs_tdfnvModemCallback)
|
||
gs_tdfnvModemCallback(Netlib_E_mcs_DISCONNECTED, lDisconnectCause);
|
||
|
||
vL0PCWin95ModemDisconnect();
|
||
break;
|
||
}
|
||
|
||
case LINECALLSTATE_CONNECTED: /* CONNECTED!!!*/
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "LINECALLSTATE_CONNECTED !!!");
|
||
#endif /* NET_USE_DEBUG */
|
||
|
||
if(gs_tdfnvModemCallback)
|
||
gs_tdfnvModemCallback(Netlib_E_mcs_CONNECTED,0);
|
||
|
||
vL0PCWin95ModemConnect();
|
||
break;
|
||
|
||
case LINECALLSTATE_OFFERING:
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "LINECALLSTATE_OFFERING");
|
||
#endif /* NET_USE_DEBUG */
|
||
if(gs_tdfnvModemCallback)
|
||
gs_tdfnvModemCallback(Netlib_E_mcs_OFFERING, 0);
|
||
|
||
vL0PCWin95ModemAnswer((HCALL)dwDevice);
|
||
break;
|
||
|
||
case LINECALLSTATE_ACCEPTED:
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "LINECALLSTATE_ACCEPTED");
|
||
#endif /* NET_USE_DEBUG */
|
||
if(gs_tdfnvModemCallback)
|
||
gs_tdfnvModemCallback(Netlib_E_mcs_ACCEPTED, 0);
|
||
|
||
break;
|
||
|
||
default:
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "Unhandled LINECALLSTATE message");
|
||
#endif /* NET_USE_DEBUG */
|
||
break;
|
||
}
|
||
}
|
||
/*************************************************************/
|
||
|
||
void L0PCWin95ModemDoLineClose(
|
||
DWORD dwDevice, DWORD dwMessage, DWORD dwCallbackInstance,
|
||
DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
|
||
{
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "LINE_CLOSE");
|
||
#endif /* NET_USE_DEBUG */
|
||
}
|
||
|
||
/*************************************************************/
|
||
|
||
void L0PCWin95ModemDoLineDevState(
|
||
DWORD dwDevice, DWORD dwMessage, DWORD dwCallbackInstance,
|
||
DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
|
||
{
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "LINE_LINEDEVSTATE");
|
||
switch(dwParam1)
|
||
{
|
||
case LINEDEVSTATE_RINGING:
|
||
vDebugFormat(Net_C_Debug_Modem, "Line Ringing.");
|
||
|
||
break;
|
||
|
||
case LINEDEVSTATE_REINIT:
|
||
/* This is an important case! Usually means that a service provider*/
|
||
/* has changed in such a way that requires TAPI to REINIT.*/
|
||
/* Note that there are both 'soft' REINITs and 'hard' REINITs.*/
|
||
/* Soft REINITs don't actually require a full shutdown but is instead*/
|
||
/* just an informational change that historically required a REINIT*/
|
||
/* to force the application to deal with. TAPI API Version 1.3 apps*/
|
||
/* will still need to do a full REINIT for both hard and soft REINITs.*/
|
||
|
||
switch(dwParam2)
|
||
{
|
||
/* This is the hard REINIT. No reason given, just REINIT.*/
|
||
/* TAPI is waiting for everyone to shutdown.*/
|
||
/* Our response is to immediately shutdown any calls,*/
|
||
/* shutdown our use of TAPI and notify the user.*/
|
||
case 0:
|
||
vDebugFormat(Net_C_Debug_Modem, "Tapi line configuration has changed.");
|
||
break;
|
||
|
||
case LINE_CREATE:
|
||
vDebugFormat(Net_C_Debug_Modem, "Soft REINIT: LINE_CREATE.");
|
||
break;
|
||
|
||
case LINE_LINEDEVSTATE:
|
||
vDebugFormat(Net_C_Debug_Modem, "Soft REINIT: LINE_LINEDEVSTATE.");
|
||
break;
|
||
|
||
/* There might be other reasons to send a soft reinit.*/
|
||
/* No need to to shutdown for these.*/
|
||
default:
|
||
vDebugFormat(Net_C_Debug_Modem, "Ignoring soft REINIT");
|
||
break;
|
||
}
|
||
break;
|
||
|
||
case LINEDEVSTATE_OUTOFSERVICE:
|
||
vDebugFormat(Net_C_Debug_Modem, "Line selected is now Out of Service.");
|
||
break;
|
||
|
||
case LINEDEVSTATE_DISCONNECTED:
|
||
vDebugFormat(Net_C_Debug_Modem, "Line selected is now disconnected.");
|
||
break;
|
||
|
||
case LINEDEVSTATE_MAINTENANCE:
|
||
vDebugFormat(Net_C_Debug_Modem, "Line selected is now out for maintenance.");
|
||
break;
|
||
|
||
case LINEDEVSTATE_TRANSLATECHANGE:
|
||
break;
|
||
|
||
case LINEDEVSTATE_REMOVED:
|
||
vDebugFormat(Net_C_Debug_Modem, "A Line device has been removed");
|
||
break;
|
||
|
||
default:
|
||
vDebugFormat(Net_C_Debug_Modem, "Unhandled LINEDEVSTATE message");
|
||
}
|
||
#endif /* NET_USE_DEBUG */
|
||
}
|
||
|
||
|
||
/*************************************************************/
|
||
|
||
void L0PCWin95ModemDoLineReply(
|
||
DWORD dwDevice, DWORD dwMessage, DWORD dwCallbackInstance,
|
||
DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
|
||
{
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "LINE_REPLY, Request ID: %ld", dwParam1);
|
||
#endif /* NET_USE_DEBUG */
|
||
|
||
if(dwParam2==0) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "OK");
|
||
#endif /* NET_USE_DEBUG */
|
||
} else {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "erreur: %x", dwParam2);
|
||
#endif /* NET_USE_DEBUG */
|
||
}
|
||
}
|
||
|
||
/*************************************************************/
|
||
|
||
void L0PCWin95ModemDoLineCreate(
|
||
DWORD dwDevice, DWORD dwMessage, DWORD dwCallbackInstance,
|
||
DWORD dwParam1, DWORD dwParam2, DWORD dwParam3)
|
||
{
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "LINE_CREATE");
|
||
#endif /* NET_USE_DEBUG */
|
||
}
|
||
|
||
/*
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_tdeErrorStatus eL0PCWin95ModemScan
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input :
|
||
cStart - flag indicating whether to step to the next modem or to restart from the beginning
|
||
dwCallerDeviceID - address of a long where the functions stores the next modem's device ID
|
||
acName - array of char where the functions stores the next modem's name
|
||
usNameLength - size of the previous array of char
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output :
|
||
a NetLib_tdeErrorStatus
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : July 9,96
|
||
Author : Christophe Roguet
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
*/
|
||
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eL0PCWin95ModemScan(char cStart, long *dwCallerDeviceID, char *acName, unsigned short usNameLength)
|
||
|
||
{
|
||
long lErrorCode;
|
||
static DWORD dwDeviceID;
|
||
DWORD dwAPIVersion;
|
||
LINEEXTENSIONID ExtensionID;
|
||
LINEDEVCAPS *pLineDevCaps;
|
||
long lNeededSize;
|
||
|
||
/* make certain TAPI has been initialized */
|
||
|
||
if(!(gs_bL0PCWin95ModemInitState&0x01))
|
||
return NetLib_E_es_ProtocolNotInitialized;
|
||
|
||
/* allocate a LINEDEVCAPS structure */
|
||
|
||
pLineDevCaps=(LINEDEVCAPS *)pMalloc(sizeof(LINEDEVCAPS));
|
||
pLineDevCaps->dwTotalSize=sizeof(LINEDEVCAPS);
|
||
|
||
if(cStart)
|
||
dwDeviceID=0;
|
||
else
|
||
dwDeviceID++;
|
||
|
||
/* clear the user data */
|
||
|
||
memset(acName, '\0', usNameLength);
|
||
*dwCallerDeviceID=-1;
|
||
|
||
/* scan the list of installed connectoids */
|
||
|
||
for(; dwDeviceID<gs_dwNumDevs; dwDeviceID++) {
|
||
|
||
lErrorCode=lineNegotiateAPIVersion(gs_hLineApp, dwDeviceID,
|
||
0x00000000, 0x000A0000, /* ??? */
|
||
&dwAPIVersion, &ExtensionID);
|
||
|
||
if(lErrorCode!=0) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "lineNegotiate(): 0x%08x", lErrorCode);
|
||
#endif /* NET_USE_DEBUG */
|
||
continue;
|
||
}
|
||
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "dwAPIVersion: 0x%08x\n", dwAPIVersion);
|
||
#endif /* NET_USE_DEBUG */
|
||
|
||
lErrorCode=lineGetDevCaps(gs_hLineApp, dwDeviceID/* device id */,
|
||
dwAPIVersion, 0 /* ext. version */,
|
||
pLineDevCaps);
|
||
|
||
if(lErrorCode!=0) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "lineGetDevCaps(): 0x%08x", lErrorCode);
|
||
#endif /* NET_USE_DEBUG */
|
||
continue;
|
||
}
|
||
|
||
/* if the device has modem capabilities, retrieve its name */
|
||
|
||
if( pLineDevCaps->dwBearerModes & LINEBEARERMODE_VOICE
|
||
&& pLineDevCaps->dwMediaModes & LINEMEDIAMODE_DATAMODEM
|
||
&& pLineDevCaps->dwLineFeatures & LINEFEATURE_MAKECALL) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "%d: modem, voix, appel ok", dwDeviceID);
|
||
vDebugFormat(Net_C_Debug_Modem, "dwMaxRate:%d", pLineDevCaps->dwMaxRate);
|
||
#endif /* NET_USE_DEBUG */
|
||
|
||
/* we may need to reallocate the LINEDEVCAPS structure */
|
||
|
||
if(pLineDevCaps->dwTotalSize<pLineDevCaps->dwNeededSize) {
|
||
|
||
lNeededSize=pLineDevCaps->dwNeededSize;
|
||
vFree((tdpPointer)pLineDevCaps);
|
||
pLineDevCaps=(LINEDEVCAPS *)pMalloc(lNeededSize);
|
||
if((tdpPointer)pLineDevCaps==C_pNull)
|
||
continue;
|
||
pLineDevCaps->dwTotalSize=lNeededSize;
|
||
|
||
lErrorCode=lineGetDevCaps(gs_hLineApp, dwDeviceID/* device id */,
|
||
dwAPIVersion, 0 /* ext. version */,
|
||
pLineDevCaps);
|
||
|
||
if(lErrorCode!=0) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "lineGetDevCaps(): 0x%08x", lErrorCode);
|
||
#endif /* NET_USE_DEBUG */
|
||
continue;
|
||
}
|
||
|
||
}
|
||
if(pLineDevCaps->dwLineNameOffset==0)
|
||
strncpy(acName, "Unknown", usNameLength-1);
|
||
else {
|
||
/* copy just the required number of chars */
|
||
/* but don't forget to leave a null character at the end of the string */
|
||
if(pLineDevCaps->dwLineNameSize<usNameLength)
|
||
usNameLength=(unsigned short)(pLineDevCaps->dwLineNameSize+1);
|
||
strncpy(acName, (char*)pLineDevCaps+pLineDevCaps->dwLineNameOffset, usNameLength-1);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
|
||
/* return the new device ID */
|
||
|
||
if(dwDeviceID==gs_dwNumDevs) { /* we reached the end of the list of installed connectoids */
|
||
*dwCallerDeviceID=(unsigned long)-1;
|
||
dwDeviceID=(unsigned long)-1; /* loop back from the beginning */
|
||
} else
|
||
*dwCallerDeviceID=dwDeviceID;
|
||
|
||
/* free the allocated LINEDEVCAPS structure */
|
||
|
||
vFree((tdpPointer)pLineDevCaps);
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Description : NetLib_tdeErrorStatus eL0PCWin95ModemAddPort
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input :
|
||
none (use the first modem in the system list of communication devices)
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output :
|
||
a NetLib_tdeErrorStatus
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : July 9,96
|
||
Author : Christophe Roguet, part of code adapted from eL0PCWin95SerialAddPort
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
*/
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eL0PCWin95ModemAddPort(long dwDeviceID)
|
||
{
|
||
long lErrorCode;
|
||
DWORD dwAPIVersion;
|
||
LINEEXTENSIONID ExtensionID;
|
||
LINEDEVCAPS LineDevCaps;
|
||
VARSTRING *pDeviceConfig;
|
||
VARSTRING *pDeviceID;
|
||
tduwNetChannel uwChannelToInit;
|
||
|
||
long lNeededSize;
|
||
|
||
HANDLE hCom;
|
||
/* COMMPROP *pCommProp;
|
||
*/
|
||
#define DEVNAMEMAXSIZE 100
|
||
|
||
char szDeviceName[DEVNAMEMAXSIZE];
|
||
|
||
/* verify the validity of the device ID */
|
||
|
||
if(dwDeviceID>=(long)gs_dwNumDevs) { /* not a valid line device ID*/
|
||
return NetLib_E_es_InvalidPortNumber; /* trouver un autre num<75>ro d'erreur */
|
||
}
|
||
|
||
lErrorCode=lineNegotiateAPIVersion(gs_hLineApp, dwDeviceID,
|
||
0x00000000, 0x000A0000, /* ??? */
|
||
&dwAPIVersion, &ExtensionID);
|
||
|
||
if(lErrorCode!=0) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "lineNegotiate(): 0x%08x", lErrorCode);
|
||
#endif /* NET_USE_DEBUG */
|
||
return NetLib_E_es_InvalidPortNumber; /* trouver un autre num<75>ro d'erreur */;
|
||
}
|
||
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "dwAPIVersion: 0x%08x\n", dwAPIVersion);
|
||
#endif /* NET_USE_DEBUG */
|
||
|
||
LineDevCaps.dwTotalSize=sizeof(LineDevCaps);
|
||
|
||
lErrorCode=lineGetDevCaps(gs_hLineApp, dwDeviceID/* device id */,
|
||
dwAPIVersion, 0 /* ext. version */,
|
||
&LineDevCaps);
|
||
|
||
if(lErrorCode!=0) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "lineGetDevCaps(): 0x%08x", lErrorCode);
|
||
#endif /* NET_USE_DEBUG */
|
||
return NetLib_E_es_InvalidPortNumber; /* trouver un autre num<75>ro d'erreur */;
|
||
}
|
||
|
||
if(!( LineDevCaps.dwBearerModes & LINEBEARERMODE_VOICE
|
||
&& LineDevCaps.dwMediaModes & LINEMEDIAMODE_DATAMODEM
|
||
&& LineDevCaps.dwLineFeatures & LINEFEATURE_MAKECALL) ) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "ModemAddPort: device ID %d is not a modem", dwDeviceID);
|
||
#endif /* NET_USE_DEBUG */
|
||
return NetLib_E_es_InvalidPortNumber; /* trouver un autre num<75>ro d'erreur */;
|
||
}
|
||
|
||
/* reset the answer flag */
|
||
|
||
gs_cModemAnswerMode=0;
|
||
|
||
/* configure the modem */
|
||
|
||
pDeviceConfig=(VARSTRING *)pMalloc(sizeof(VARSTRING)+sizeof(DEVCFGHDR)+sizeof(COMMCONFIG)+sizeof(MODEMSETTINGS));
|
||
|
||
if(pDeviceConfig==(VARSTRING *)C_pNull) {
|
||
return NetLib_E_es_NotEnoughMemory;
|
||
}
|
||
|
||
pDeviceConfig->dwTotalSize=sizeof(VARSTRING)+sizeof(DEVCFGHDR)+sizeof(COMMCONFIG)+sizeof(MODEMSETTINGS);
|
||
|
||
lErrorCode=lineGetDevConfig(dwDeviceID, pDeviceConfig, "comm/datamodem");
|
||
|
||
if(lErrorCode!=0) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "lineGetDevConfig(): 0x%08x", lErrorCode);
|
||
#endif /* NET_USE_DEBUG */
|
||
return NetLib_E_es_InvalidPortNumber;
|
||
}
|
||
|
||
vL0PCWin95ModemInitializeCommConfig(
|
||
&(((DEVCFG *)((char *)pDeviceConfig+pDeviceConfig->dwStringOffset))->commconfig));
|
||
|
||
lErrorCode=lineSetDevConfig(dwDeviceID, (char *)pDeviceConfig+pDeviceConfig->dwStringOffset, pDeviceConfig->dwStringSize, "comm/datamodem");
|
||
|
||
if(lErrorCode!=0) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "lineSetDevConfig(): 0x%08x", lErrorCode);
|
||
#endif /* NET_USE_DEBUG */
|
||
return NetLib_E_es_InvalidPortNumber;
|
||
}
|
||
|
||
lErrorCode=lineOpen(gs_hLineApp, dwDeviceID, &gs_hLine,
|
||
dwAPIVersion, 0 /* dwExtVersion */, 0 /* dwCallbackInstance */,
|
||
LINECALLPRIVILEGE_OWNER, LINEMEDIAMODE_DATAMODEM, 0);
|
||
|
||
if(lErrorCode!=0) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "lineOpen(): 0x%08x", lErrorCode);
|
||
#endif /* NET_USE_DEBUG */
|
||
return NetLib_E_es_InvalidPortNumber;
|
||
}
|
||
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "lineOpen()->hLine: 0x%08x\n", gs_hLine);
|
||
#endif /* NET_USE_DEBUG */
|
||
|
||
/* request notification of state changes */
|
||
|
||
lErrorCode=lineSetStatusMessages(
|
||
gs_hLine,
|
||
/* DWORD dwLineStates */
|
||
LINEDEVSTATE_RINGING |
|
||
LINEDEVSTATE_CONNECTED | /* Important state!*/
|
||
LINEDEVSTATE_DISCONNECTED | /* Important state!*/
|
||
LINEDEVSTATE_OUTOFSERVICE | /* Important state!*/
|
||
LINEDEVSTATE_MAINTENANCE | /* Important state!*/
|
||
LINEDEVSTATE_REINIT /* Not allowed to disable this.*/
|
||
,
|
||
/*DWORD dwAddressStates */
|
||
0
|
||
);
|
||
|
||
if(lErrorCode!=0) {
|
||
lineClose(gs_hLine);
|
||
gs_hLine=0;
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "lineSetStatusMessage(): 0x%08x", lErrorCode);
|
||
#endif /* NET_USE_DEBUG */
|
||
return NetLib_E_es_InvalidPortNumber;
|
||
}
|
||
|
||
/* retrieve the associated device ID */
|
||
|
||
/* allocate a memory block for a VARSTRING structure plus 30 bytes of data */
|
||
|
||
pDeviceID=(VARSTRING *)pMalloc(30+sizeof(VARSTRING));
|
||
|
||
if(pDeviceID==(VARSTRING *)C_pNull) {
|
||
lineClose(gs_hLine);
|
||
gs_hLine=0;
|
||
return NetLib_E_es_NotEnoughMemory;
|
||
}
|
||
|
||
pDeviceID->dwTotalSize=30+sizeof(VARSTRING);
|
||
|
||
lErrorCode=lineGetID(gs_hLine, 0 /*dwAddressID ignore*/ , 0 /*hCall ignore */,
|
||
LINECALLSELECT_LINE, pDeviceID, "comm/datamodem");
|
||
|
||
if(lErrorCode!=0) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "lineGetID(): 0x%08x", lErrorCode);
|
||
#endif /* NET_USE_DEBUG */
|
||
lineClose(gs_hLine);
|
||
gs_hLine=0;
|
||
return NetLib_E_es_InvalidPortNumber;
|
||
}
|
||
|
||
/* we may need to reallocate the VARSTRING structure */
|
||
|
||
if(pDeviceID->dwTotalSize<pDeviceID->dwNeededSize) {
|
||
lNeededSize=pDeviceID->dwNeededSize;
|
||
vFree((tdpPointer)pDeviceID);
|
||
pDeviceID=(VARSTRING *)pMalloc(lNeededSize);
|
||
pDeviceID->dwTotalSize=lNeededSize;
|
||
lErrorCode=lineGetID(gs_hLine, 0 /*dwAddressID ignore*/ , 0 /*hCall ignore */,
|
||
LINECALLSELECT_LINE, pDeviceID, "comm/datamodem");
|
||
|
||
if(lErrorCode!=0) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "lineGetID(): 0x%08x", lErrorCode);
|
||
#endif /* NET_USE_DEBUG */
|
||
lineClose(gs_hLine);
|
||
gs_hLine=0;
|
||
return NetLib_E_es_InvalidPortNumber;
|
||
}
|
||
|
||
}
|
||
|
||
if(pDeviceID->dwStringFormat!=STRINGFORMAT_BINARY) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "pDeviceID->dwStringFormat!=STRINGFORMAT_BINARY ??");
|
||
#endif /* NET_USE_DEBUG */
|
||
lineClose(gs_hLine);
|
||
gs_hLine=0;
|
||
return NetLib_E_es_InvalidPortNumber;
|
||
}
|
||
|
||
/* retrieve the associated communication port handle */
|
||
|
||
hCom=*(HANDLE*)(((char *)pDeviceID)+pDeviceID->dwStringOffset);
|
||
strncpy(szDeviceName, (((char *)pDeviceID)+pDeviceID->dwStringOffset+sizeof(HANDLE)), DEVNAMEMAXSIZE);
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "%d: %s", dwDeviceID, szDeviceName);
|
||
#endif /* NET_USE_DEBUG */
|
||
|
||
vFree((tdpPointer)pDeviceID);
|
||
|
||
/* now that we have a COM port, initialize a channel with it */
|
||
|
||
/* how to find the index of the com port associated to the modem ???*/
|
||
/* as for now, we use the last serial channel, which is reserved for the modem */
|
||
|
||
uwChannelToInit = C_ModemSpecialChannel;
|
||
|
||
/* any failure will cause the channel to be marked as unavailable */
|
||
gs_a_stL0PCWin95SerialChannels[uwChannelToInit].ubf1IsSlotInUse = 0;
|
||
|
||
if(gs_a_stL0PCWin95SerialChannels[uwChannelToInit].hCom == INVALID_HANDLE_VALUE)
|
||
gs_a_stL0PCWin95SerialChannels[uwChannelToInit].hCom = hCom;
|
||
else { /* the modem slot is already used ??? */
|
||
|
||
lineClose(gs_hLine);
|
||
gs_hLine=0;
|
||
|
||
return NetLib_E_es_SerialFileCreationFailure; /* new modem error code ? */
|
||
}
|
||
|
||
/* this is a channel usable to send broadcast messages */
|
||
gs_a_stL0PCWin95SerialChannels[uwChannelToInit].ubf1IsBroadcast = 1;
|
||
|
||
/* this is a channel for the modem layer */
|
||
gs_a_stL0PCWin95SerialChannels[uwChannelToInit].ubf1IsSlotForModem= 1;
|
||
|
||
/* the modem line is not connected to a remote end yet */
|
||
gs_a_stL0PCWin95SerialChannels[uwChannelToInit].ubf1IsSlotConnected= 0;
|
||
|
||
/* line baud rate setting : POSTPONED until I understand how exactly it works ... */
|
||
/* the modem rate should be no more than the serial port rate */
|
||
/* the modems negotiate the rate they use at connect time */
|
||
gs_a_stL0PCWin95SerialChannels[uwChannelToInit].eChannelStatus = E_ts_OK;
|
||
|
||
gs_a_stL0PCWin95SerialChannels[uwChannelToInit].ubf1IsSlotInUse = 1;
|
||
|
||
/* copy the configuration into the channel structure */
|
||
/* (but the modemsettings gets lost) */
|
||
|
||
memcpy(&gs_a_stL0PCWin95SerialChannels[uwChannelToInit].stChannelStatus,
|
||
&(((DEVCFG *)((char *)pDeviceConfig+pDeviceConfig->dwStringOffset))->commconfig.dcb), sizeof(DCB));
|
||
|
||
/* now we can free the device structure */
|
||
|
||
vFree((tdpPointer)pDeviceConfig);
|
||
|
||
gs_bL0PCWin95ModemInitState = gs_bL0PCWin95ModemInitState | (char)0x04;
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Description : void vL0PCWin95ModemAnswer
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input :
|
||
handle to the call to be answered
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output :
|
||
none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : July 10,96
|
||
Author : Christophe Roguet
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
*/
|
||
void vL0PCWin95ModemAnswer(HCALL hCallToAnswer)
|
||
{
|
||
long lErrorCode;
|
||
|
||
/* if there is no call in progress and we should accept incoming calls, */
|
||
/* then accept the incoming call, else reject it */
|
||
|
||
if(!gs_hCall && gs_cModemAnswerMode) {
|
||
lErrorCode=lineAnswer(hCallToAnswer, NULL, 0);
|
||
if(lErrorCode<0) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "ModemAnswer(): lineAnswer(): 0x%08x", lErrorCode);
|
||
#endif /* NET_USE_DEBUG */
|
||
return;
|
||
}
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "ModemAnswer(): lineAnswer(): -->Request ID: %d", lErrorCode);
|
||
#endif /* NET_USE_DEBUG */
|
||
gs_hCall=hCallToAnswer;
|
||
} else {
|
||
lErrorCode=lineDrop(hCallToAnswer, NULL, 0);
|
||
if(lErrorCode<0) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "ModemAnswer(): lineDrop(): 0x%08x", lErrorCode);
|
||
#endif /* NET_USE_DEBUG */
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|
||
/*
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Description : void vL0PCWin95ModemConnect
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input :
|
||
none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output :
|
||
none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : July 10,96
|
||
Author : Christophe Roguet
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
*/
|
||
void vL0PCWin95ModemConnect()
|
||
|
||
{
|
||
long lErrorCode;
|
||
tduwNetChannel uwChannelToInit; /* index of channel to init */
|
||
tdstL0PCWin95SerialChannel *pstChannel; /* pointer to channel to init */
|
||
COMMTIMEOUTS cto; /* communication timeouts */
|
||
int iNotOk; /* flag: has a problem occured so far ?*/
|
||
|
||
/* as for now, the modem uses the last serial channel */
|
||
|
||
uwChannelToInit=C_ModemSpecialChannel;
|
||
pstChannel=&gs_a_stL0PCWin95SerialChannels[uwChannelToInit];
|
||
|
||
/* the connection has been established: */
|
||
/* the channel can be used to communicate */
|
||
/* allocate handles and buffers, and mark channel as connected */
|
||
|
||
/* set transmission timeouts */
|
||
|
||
#ifdef MODEM_DEBUG
|
||
if(GetCommTimeouts(pstChannel->hCom, &cto)==FALSE) {
|
||
lErrorCode=GetLastError();
|
||
fprintf(stderr, "GetCommTimeouts(): %d\n", lErrorCode);
|
||
}
|
||
|
||
DisplayCommTimeouts(&cto);
|
||
puts("---------------------------------");
|
||
|
||
#endif /* MODEM_DEBUG */
|
||
|
||
if(SetupComm(pstChannel->hCom, 500, 2*sizeof(tdstPacket))==FALSE) {
|
||
lErrorCode=GetLastError();
|
||
#ifdef MODEM_DEBUG
|
||
fprintf(stderr, "GetCommTimeouts(): %d\n", lErrorCode);
|
||
#endif /* MODEM_DEBUG */
|
||
}
|
||
|
||
vL0PCWin95ModemInitializeCommTimeouts(&cto);
|
||
|
||
if(SetCommTimeouts(pstChannel->hCom, &cto)==FALSE) {
|
||
lErrorCode=GetLastError();
|
||
#ifdef MODEM_DEBUG
|
||
printf("SetCommTimeouts(): %d\n", lErrorCode);
|
||
#endif /* MODEM_DEBUG */
|
||
}
|
||
|
||
#ifdef MODEM_DEBUG
|
||
DisplayCommTimeouts(&cto);
|
||
puts("---------------------------------");
|
||
#endif /* MODEM_DEBUG */
|
||
|
||
/* purge transmission channel from any extraneous lingering data */
|
||
|
||
if (!PurgeComm(pstChannel->hCom, PURGE_RXCLEAR | PURGE_TXCLEAR)) {
|
||
lErrorCode=GetLastError();
|
||
/* close the handle */
|
||
CloseHandle(pstChannel->hCom);
|
||
pstChannel->hCom = INVALID_HANDLE_VALUE;
|
||
|
||
pstChannel->eChannelStatus = E_ts_ChannelUnitialized; /* ? */
|
||
/* CLOSE AND DEALLOCATE THE CALL ??? ModemRelease ?? */
|
||
return /* NetLib_E_es_SerialInitFailure */;
|
||
}
|
||
|
||
ClearCommBreak(pstChannel->hCom);
|
||
|
||
iNotOk=0;
|
||
|
||
/* initialize the low level emission/reception buffers */
|
||
|
||
vInitWindow(&pstChannel->stSendWindow, MODEM_WINDOW, MODEM_TIMEOUT);
|
||
vInitWindow(&pstChannel->stRecvWindow, MODEM_WINDOW, 0);
|
||
|
||
pstChannel->ucSeqn=0;
|
||
pstChannel->ulReadPos=0;
|
||
|
||
vInitRingBuffer(&pstChannel->stSendBuffer);
|
||
vInitLinkBuffer(&pstChannel->stRecvBuffer, MODEM_LINKNUMBER);
|
||
|
||
pstChannel->hBufferEmpty=CreateEvent(NULL, TRUE, FALSE, NULL);
|
||
pstChannel->hSlotsEmpty=CreateEvent(NULL, TRUE, FALSE, NULL);
|
||
|
||
InitializeCriticalSection(&pstChannel->stSendBufferAccess);
|
||
InitializeCriticalSection(&pstChannel->stRecvBufferAccess);
|
||
|
||
/* no operation in progress yet */
|
||
pstChannel->ubf1ReadInProgress
|
||
= pstChannel->ubf1WriteInProgress = 0;
|
||
|
||
/* no byte received or sent in any I/O operation yet */
|
||
pstChannel->ulBytesInReadBuffer = 0;
|
||
|
||
/* allocate buffer for reception */
|
||
pstChannel->pCurrentReceivingBuffer = pMalloc(C_uwMaxAsyncLength);
|
||
if(pstChannel->pCurrentReceivingBuffer!=C_pNull) {
|
||
|
||
/* register with the threada controller */
|
||
|
||
vAddThreadClient(uwChannelToInit);
|
||
|
||
/* start the ball rolling: signal the read event */
|
||
|
||
if(SetEvent(pstChannel->stOverlappedRead.hEvent)==TRUE) {
|
||
pstChannel->pCurrentReceivedMessage=C_pNull;
|
||
pstChannel->pCurrentMessageIncomingPoint=C_pNull;
|
||
pstChannel->ulBytesToCompleteIncomingMessage=0L;
|
||
pstChannel->ubf1IsSlotConnected= 1;
|
||
} else {
|
||
iNotOk=1;
|
||
/* deregister from the thread controller */
|
||
vRemoveThreadClient(uwChannelToInit);
|
||
}
|
||
} else iNotOk=1; /* NetLib_E_es_NotEnoughMemory */
|
||
|
||
if(iNotOk) {
|
||
/* close the handle */
|
||
CloseHandle(pstChannel->hCom);
|
||
pstChannel->hCom = INVALID_HANDLE_VALUE;
|
||
|
||
DeleteCriticalSection(&pstChannel->stSendBufferAccess);
|
||
DeleteCriticalSection(&pstChannel->stRecvBufferAccess);
|
||
|
||
CloseHandle(pstChannel->hBufferEmpty);
|
||
CloseHandle(pstChannel->hSlotsEmpty);
|
||
|
||
vDeleteLinkBuffer(&pstChannel->stRecvBuffer);
|
||
|
||
vDeleteWindow(&pstChannel->stRecvWindow);
|
||
vDeleteWindow(&pstChannel->stSendWindow);
|
||
|
||
pstChannel->eChannelStatus = E_ts_ChannelUnitialized; /* ? */
|
||
}
|
||
}
|
||
|
||
/*
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Description : void vL0PCWin95ModemDisconnect
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input :
|
||
none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output :
|
||
none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
This function is called when the line gets disconnected.
|
||
|
||
Creation date : July 14,96
|
||
Author : Christophe Roguet
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
*/
|
||
void vL0PCWin95ModemDisconnect()
|
||
|
||
{
|
||
tduwNetChannel uwChannelToClose; /* index of channel disconnected */
|
||
tdstL0PCWin95SerialChannel *pstChannel; /* pointer to this channel */
|
||
|
||
/* as for now, the modem uses the last serial channel */
|
||
|
||
uwChannelToClose=C_ModemSpecialChannel;
|
||
pstChannel=&gs_a_stL0PCWin95SerialChannels[uwChannelToClose];
|
||
|
||
/* the connection has been broken: */
|
||
vL0PCWin95SerialCloseChannel(uwChannelToClose);
|
||
|
||
/* the resources held by the channel are deallocated when the line becomes idle */
|
||
}
|
||
/*
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Description : void vL0PCWin95ModemRelease
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input :
|
||
none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output :
|
||
none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
This function is called when the line becomes idle.
|
||
|
||
Creation date : July 14,96
|
||
Author : Christophe Roguet
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
*/
|
||
void vL0PCWin95ModemRelease(HCALL hCallToRelease)
|
||
|
||
{
|
||
long lErrorCode;
|
||
|
||
tduwNetChannel uwChannelToClose; /* index of channel disconnected */
|
||
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "ModemRelease()");
|
||
#endif /* NET_USE_DEBUG */
|
||
/* the line has become idle : deallocate what needs to be deallocated */
|
||
|
||
/* is this a call that we rejected ? */
|
||
|
||
if(hCallToRelease!=gs_hCall) {
|
||
/* yes: simply deallocate the call */
|
||
lErrorCode=lineDeallocateCall(hCallToRelease);
|
||
|
||
if(lErrorCode!=0) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "ModemRelease():lineDeallocateCall()1: 0x%08x", lErrorCode);
|
||
#endif /* NET_USE_DEBUG */
|
||
} else {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "ModemRelease():lineDeallocateCall()1: OK");
|
||
#endif /* NET_USE_DEBUG */
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
/* deallocate the call used by the previous connection */
|
||
|
||
/* as for now, the modem uses the last serial channel */
|
||
|
||
/* because of the I/O thread, we can't just close the handle ... we have to close the channel */
|
||
|
||
uwChannelToClose=C_ModemSpecialChannel;
|
||
|
||
vL0PCWin95SerialCloseChannel(uwChannelToClose);
|
||
|
||
lErrorCode=lineDeallocateCall(gs_hCall);
|
||
|
||
if(lErrorCode!=0) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "ModemRelease():lineDeallocateCall()2: 0x%08x", lErrorCode);
|
||
#endif /* NET_USE_DEBUG */
|
||
return;
|
||
} else {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "ModemRelease():lineDeallocateCall()2: OK");
|
||
#endif /* NET_USE_DEBUG */
|
||
}
|
||
|
||
gs_hCall=0;
|
||
|
||
if(gs_hWaitForRelease!=INVALID_HANDLE_VALUE)
|
||
SetEvent(gs_hWaitForRelease);
|
||
else {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "ModemRelease(): ?? hWaitForRelease invalide");
|
||
#endif /* NET_USE_DEBUG */
|
||
}
|
||
}
|
||
/*
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Description : void vL0PCWin95ModemExitTAPI
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input :
|
||
none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output :
|
||
none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : July 10,96
|
||
Author : Christophe Roguet
|
||
This function closes the line, if needed, and detaches from the TAPI, if needed.
|
||
IT MUST BE CALLED WHENEVER THE APPLICATION IS LEFT, if not, TAPI gets stuck() ...
|
||
Modification log:
|
||
Date: Author
|
||
8/11/96 Christophe Roguet
|
||
moved part of code into ModemCloseProtocol()
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
*/
|
||
|
||
void vL0PCWin95ModemExitTAPI()
|
||
|
||
{
|
||
long lErrorCode;
|
||
|
||
/* if the line is still open, close it */
|
||
/* (if there was no call in progress, ModemCloseChannel did not close the line) */
|
||
|
||
if(gs_hLine) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "avant lineClose(%lx)", gs_hLine);
|
||
#endif /* NET_USE_DEBUG */
|
||
lErrorCode=lineClose(gs_hLine);
|
||
|
||
if(lErrorCode!=0) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "lineClose(): 0x%08x", lErrorCode);
|
||
#endif /* NET_USE_DEBUG */
|
||
} else
|
||
gs_hLine=0L;
|
||
}
|
||
|
||
if(gs_hLineApp) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "avant lineShutdown(%lx)", gs_hLineApp);
|
||
#endif /* NET_USE_DEBUG */
|
||
lErrorCode=lineShutdown(gs_hLineApp);
|
||
|
||
if(lErrorCode!=0) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "lineShutdown(): 0x%08x", lErrorCode);
|
||
#endif /* NET_USE_DEBUG */
|
||
} else
|
||
gs_hLineApp=0L;
|
||
}
|
||
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "fin de vL0PCWin95ModemExitTAPI");
|
||
#endif /* NET_USE_DEBUG */
|
||
}
|
||
/*****************************************************************************
|
||
*
|
||
* Description: eL0PCWin95ModemDial
|
||
*
|
||
* dials a phone call and initiates connection
|
||
*
|
||
*****************************************************************************
|
||
*
|
||
* Input: telephone number represented as a string
|
||
*
|
||
* Output: an error code
|
||
*
|
||
*****************************************************************************
|
||
* Creation Date: July 10, 1996 Author: Christophe ROGUET
|
||
*****************************************************************************
|
||
*
|
||
* Modification log:
|
||
*
|
||
* Date: Author:
|
||
*
|
||
****************************************************************************/
|
||
|
||
NetLib_tdeErrorStatus _NET_CALLING_CONV_ eL0PCWin95ModemDial(char *pcNumberString)
|
||
{
|
||
int iNumberLength;
|
||
long lErrorCode;
|
||
long RequestID;
|
||
|
||
/* should test the validity of hLine etc ... */
|
||
/* should avoid reentering calls */
|
||
|
||
iNumberLength=1+strlen(pcNumberString);
|
||
|
||
/* allocate a block for holding the call parameters plus the string that contains */
|
||
/* the called number */
|
||
|
||
lpCallParams=(LINECALLPARAMS *)pMalloc(iNumberLength + sizeof( LINECALLPARAMS ));
|
||
memset(lpCallParams, 0, iNumberLength + sizeof( LINECALLPARAMS ));
|
||
|
||
lpCallParams -> dwTotalSize = iNumberLength + sizeof( LINECALLPARAMS );
|
||
|
||
/* This is where we configure the line for DATAMODEM usage.*/
|
||
lpCallParams -> dwBearerMode = LINEBEARERMODE_VOICE;
|
||
lpCallParams -> dwMediaMode = LINEMEDIAMODE_DATAMODEM;
|
||
|
||
/* This specifies that we want to use only IDLE calls and*/
|
||
/* don't want to cut into a call that might not be IDLE (ie, in use).*/
|
||
lpCallParams -> dwCallParamFlags = LINECALLPARAMFLAGS_IDLE;
|
||
|
||
/* if there are multiple addresses on line, use first anyway.*/
|
||
/* It will take a more complex application than a simple tty app*/
|
||
/* to use multiple addresses on a line anyway.*/
|
||
lpCallParams -> dwAddressMode = LINEADDRESSMODE_ADDRESSID;
|
||
lpCallParams -> dwAddressID = 0;
|
||
|
||
/* Since we don't know where we originated, leave these blank.*/
|
||
lpCallParams -> dwOrigAddressSize = 0;
|
||
lpCallParams -> dwOrigAddressOffset = 0;
|
||
|
||
/* Unimodem ignores these values.*/
|
||
(lpCallParams -> DialParams) . dwDialSpeed = 0;
|
||
(lpCallParams -> DialParams) . dwDigitDuration = 0;
|
||
(lpCallParams -> DialParams) . dwDialPause = 0;
|
||
(lpCallParams -> DialParams) . dwWaitForDialtone = 0;
|
||
|
||
/* Address we are dialing.*/
|
||
lpCallParams -> dwDisplayableAddressOffset = sizeof(LINECALLPARAMS);
|
||
lpCallParams -> dwDisplayableAddressSize = iNumberLength;
|
||
strcpy((LPSTR)lpCallParams + sizeof(LINECALLPARAMS), pcNumberString);
|
||
|
||
/* baud rate range ???*/
|
||
|
||
lpCallParams -> dwMinRate= 0;
|
||
lpCallParams -> dwMaxRate= 0;
|
||
|
||
lErrorCode=lineMakeCall(gs_hLine, &gs_hCall, pcNumberString,0 /* dwCountryCode */, lpCallParams );
|
||
|
||
if(lErrorCode<0) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "lineMakeCall(): 0x%08x", lErrorCode);
|
||
#endif /* NET_USE_DEBUG */
|
||
return NetLib_E_es_UnknownError; /* add a new error code */
|
||
} else RequestID=lErrorCode;
|
||
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "lineMakeCall()->RequestID: %d\n", RequestID);
|
||
#endif /* NET_USE_DEBUG */
|
||
|
||
vFree((tdpPointer)lpCallParams);
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*****************************************************************************
|
||
*
|
||
* Description: eL0PCWin95ModemAnswerMode
|
||
*
|
||
* this function indicates whether incoming calls should be accepted or rejected
|
||
*
|
||
*****************************************************************************
|
||
*
|
||
* Input: boolean: non zero means 'answer any incoming call'
|
||
*
|
||
* Output: none
|
||
*
|
||
*****************************************************************************
|
||
* Creation Date: August 5, 1996 Author: Christophe ROGUET
|
||
*****************************************************************************
|
||
*
|
||
* Modification log:
|
||
*
|
||
* Date: Author:
|
||
*
|
||
****************************************************************************/
|
||
|
||
void _NET_CALLING_CONV_ vL0PCWin95ModemAnswerMode(char cMode)
|
||
|
||
{
|
||
gs_cModemAnswerMode=cMode;
|
||
}
|
||
|
||
/*
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Description : vL0PCWin95ModemCloseChannel
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input :
|
||
the channel to close - not actually used yet. the modem must be on the last serial channel
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output :
|
||
none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : July 17,96
|
||
Author : Christophe Roguet
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
*/
|
||
|
||
void vL0PCWin95ModemCloseChannel(tduwNetChannel uwChannel)
|
||
|
||
{
|
||
long lErrorCode;
|
||
DWORD dwWaitResult;
|
||
int bBreak;
|
||
unsigned long ulStopTime;
|
||
MSG msg;
|
||
|
||
/* as for now, the modem uses the last serial channel */
|
||
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "CloseChannel(%d)", uwChannel);
|
||
#endif /* NET_USE_DEBUG */
|
||
|
||
if(uwChannel!=C_ModemSpecialChannel) /* refuse to close a channel but the last one */
|
||
return;
|
||
|
||
/* close the communication port */
|
||
|
||
vL0PCWin95SerialCloseChannel(uwChannel);
|
||
|
||
/* hang up the phone */
|
||
|
||
lErrorCode=0;
|
||
|
||
if(gs_hCall) {
|
||
gs_hWaitForRelease=CreateEvent(NULL, TRUE, FALSE, NULL);
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "CloseChannel(): lineDrop()");
|
||
#endif /* NET_USE_DEBUG */
|
||
lErrorCode=lineDrop(gs_hCall, NULL/* user to user info */, 0);
|
||
}
|
||
|
||
if(lErrorCode<0) {
|
||
CloseHandle(gs_hWaitForRelease);
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "CloseChannel(): lineDrop(): 0x%08x", lErrorCode);
|
||
#endif /* NET_USE_DEBUG */
|
||
return;
|
||
} else if(lErrorCode>0) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "CloseChannel(): lineDrop()-->RequestID: %d", lErrorCode);
|
||
#endif /* NET_USE_DEBUG */
|
||
|
||
/* leave time for the asynchronous call deallocation */
|
||
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "CloseChannel(): WaitForRelease");
|
||
#endif /* NET_USE_DEBUG */
|
||
|
||
if(gs_hWaitForRelease==NULL) {
|
||
lErrorCode=GetLastError();
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "CloseChannel(): CreateEvent(): 0x%08x", lErrorCode);
|
||
#endif /* NET_USE_DEBUG */
|
||
return;
|
||
}
|
||
|
||
/* if the closing thread is not the same thread that initialized the protocol */
|
||
/* then simply wait for the deinitialisation to proceed */
|
||
/* else process windows messages until deinitialisation is done */
|
||
|
||
if(GetCurrentThreadId()!=gs_dwInitialiserThreadId)
|
||
dwWaitResult=WaitForSingleObject(gs_hWaitForRelease, 3000);
|
||
else {
|
||
bBreak=0;
|
||
ulStopTime=GetTickCount()+3000;
|
||
do {
|
||
dwWaitResult=MsgWaitForMultipleObjects(1, &gs_hWaitForRelease, FALSE, 50, QS_ALLINPUT);
|
||
switch(dwWaitResult) {
|
||
case WAIT_OBJECT_0:
|
||
bBreak=1;
|
||
break;
|
||
case WAIT_OBJECT_0+1:
|
||
GetMessage(&msg, NULL, 0, 0);
|
||
TranslateMessage(&msg);
|
||
DispatchMessage(&msg);
|
||
break;
|
||
case WAIT_ABANDONED_0:
|
||
bBreak=1;
|
||
break;
|
||
|
||
case WAIT_TIMEOUT:
|
||
if(GetTickCount()>ulStopTime)
|
||
bBreak=1;
|
||
break;
|
||
}
|
||
} while(!bBreak);
|
||
}
|
||
|
||
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "CloseChannel(): deblocage lineDrop()");
|
||
#endif /* NET_USE_DEBUG */
|
||
|
||
CloseHandle(gs_hWaitForRelease);
|
||
|
||
gs_hWaitForRelease=INVALID_HANDLE_VALUE;
|
||
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "CloseChannel(): retour WaitForRelease: %ld", dwWaitResult);
|
||
#endif /* NET_USE_DEBUG */
|
||
|
||
} else {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "CloseChannel():lineDrop()-->0 ????");
|
||
#endif /* NET_USE_DEBUG */
|
||
}
|
||
|
||
/* close the line (if it hasn't been asynchronously deallocated) */
|
||
|
||
if(gs_hLine) {
|
||
lErrorCode=lineClose(gs_hLine);
|
||
if(lErrorCode!=0) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "CloseChannel():lineClose(): 0x%08x", lErrorCode);
|
||
#endif /* NET_USE_DEBUG */
|
||
return;
|
||
}
|
||
gs_hLine=0;
|
||
}
|
||
|
||
/* we have to reset the overlapped IO operations events here, because they seem to get signaled after lineClose() */
|
||
|
||
if(ResetEvent(gs_a_stL0PCWin95SerialChannels[uwChannel].stOverlappedRead.hEvent)==FALSE)
|
||
lErrorCode=GetLastError();
|
||
if(ResetEvent(gs_a_stL0PCWin95SerialChannels[uwChannel].stOverlappedWrite.hEvent)==FALSE)
|
||
lErrorCode=GetLastError();
|
||
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "sortie CloseChannel(%d)", uwChannel);
|
||
#endif /* NET_USE_DEBUG */
|
||
}
|
||
/*
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Description : vL0PCWin95ModemClosePort
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Input :
|
||
none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Output :
|
||
none
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
Creation date : July 27,96
|
||
Author : Christophe Roguet
|
||
remark:
|
||
This is an interface function to close a particular modem. As long as the library
|
||
manages only one modem channel, this function takes no parameter.
|
||
////////////////////////////////////////////////////////////////////////////////
|
||
*/
|
||
|
||
void _NET_CALLING_CONV_ vL0PCWin95ModemClosePort(void)
|
||
|
||
{
|
||
vL0PCWin95ModemCloseChannel(C_ModemSpecialChannel);
|
||
}
|
||
|
||
/*****************************************************************************
|
||
*
|
||
* Description: vL0PCWin95ModemSetCallback
|
||
*
|
||
* sets the global variable used to store the callback function through which
|
||
* the application that uses the library gets notified of the progress of the
|
||
* connection process
|
||
*
|
||
*****************************************************************************
|
||
*
|
||
* Input: a pointer to the callback function
|
||
*
|
||
* Output: none
|
||
*
|
||
*****************************************************************************
|
||
* Creation Date: November 6th, 1996 Author: Christophe ROGUET
|
||
*****************************************************************************
|
||
*
|
||
* Modification log:
|
||
*
|
||
* Date: Author:
|
||
*
|
||
****************************************************************************/
|
||
|
||
void _NET_CALLING_CONV_ vL0PCWin95ModemSetCallback(tdfnvModemCallback CallbackFunction)
|
||
|
||
{
|
||
/* register the function's address */
|
||
gs_tdfnvModemCallback=CallbackFunction;
|
||
/* initialize the state to idle */
|
||
CallbackFunction(Netlib_E_mcs_IDLE, 0);
|
||
}
|
||
|
||
/*****************************************************************************
|
||
*
|
||
* Description: eL0PCWin95InitModem
|
||
*
|
||
* initializes the TAPI
|
||
*
|
||
*****************************************************************************
|
||
*
|
||
* Input: none
|
||
*
|
||
* Output: an error code
|
||
*
|
||
*****************************************************************************
|
||
* Creation Date: July 9, 1996 Author: Christophe ROGUET
|
||
*****************************************************************************
|
||
*
|
||
* Modification log:
|
||
*
|
||
* Date: Author:
|
||
*
|
||
****************************************************************************/
|
||
|
||
NetLib_tdeErrorStatus eL0PCWin95InitModem(void)
|
||
{
|
||
long lErrorCode;
|
||
|
||
/* global variables */
|
||
|
||
gs_dwNumDevs=0; /* number of available line devices */
|
||
gs_hLine=0; /* line ID */
|
||
gs_hCall=0; /* call ID */
|
||
lpCallParams=0; /* parameters for a call */
|
||
|
||
gs_hWaitForRelease=INVALID_HANDLE_VALUE; /* Event for synchronization of call deallocation */
|
||
|
||
gs_pstCommConfig=0; /* modem configuration */
|
||
gs_ulCommConfigSize=0;
|
||
|
||
gs_cModemAnswerMode=0; /* reject incoming calls */
|
||
gs_tdfnvModemCallback=(tdfnvModemCallback)0; /* no callback function */
|
||
|
||
if((lErrorCode=lineInitialize(&gs_hLineApp, gs_hInstance, vL0PCWin95ModemCallback,
|
||
"NetLib", &gs_dwNumDevs))!=0) {
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "InitModem(): lineInitialize() -> %lx", lErrorCode);
|
||
#endif
|
||
return NetLib_E_es_InitialisationModemError;
|
||
}
|
||
|
||
gs_bL0PCWin95ModemInitState = gs_bL0PCWin95ModemInitState | (char)0x02;
|
||
|
||
return NetLib_E_es_NoError;
|
||
}
|
||
|
||
/*****************************************************************************
|
||
*
|
||
* Description: void vL0PCWin95ModemOpenProtocol
|
||
*
|
||
* initialize the specified interface structure with the correct function
|
||
* pointers to enable a protocol-independent data transmission process.
|
||
*
|
||
*****************************************************************************
|
||
*
|
||
* Input: p_stProtocolInterface, pointer to the interface structure
|
||
*
|
||
* Output: none
|
||
*
|
||
*****************************************************************************
|
||
* Creation Date: July 9, 1996 Author: Christophe ROGUET
|
||
*****************************************************************************
|
||
*
|
||
* Modification log:
|
||
*
|
||
* Date: Author:
|
||
*
|
||
****************************************************************************/
|
||
void _NET_CALLING_CONV_ vL0PCWin95ModemOpenProtocol(HINSTANCE hInstance, unsigned long ulRate)
|
||
{
|
||
tdstNetProtocolInterface *p_stProtocolInterface;
|
||
|
||
/* first, test whether the protocol has already been opened */
|
||
/* so as not to open it twice */
|
||
/* TO WRITE */
|
||
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "ModemOpenProtocol()");
|
||
#endif
|
||
|
||
gs_hInstance=hInstance;
|
||
|
||
gs_bL0PCWin95ModemInitState = 0x00;
|
||
|
||
gs_ulL0PCWin95ModemBaudRate=ulRate;
|
||
|
||
/* initialize TAPI() */
|
||
|
||
if(eL0PCWin95InitModem()!=NetLib_E_es_NoError)
|
||
return;
|
||
|
||
/* store the current thread ID */
|
||
|
||
gs_dwInitialiserThreadId=GetCurrentThreadId();
|
||
|
||
p_stProtocolInterface=pstLevel1AddProtocol();
|
||
|
||
/* logical identification of the protocol */
|
||
p_stProtocolInterface->eProtocol = E_Net_pr_Windows95ModemProtocol;
|
||
|
||
/* setup the function pointers */
|
||
p_stProtocolInterface->fn_uwStartChannelScan = uwL0PCWin95ModemStartChannelScan;
|
||
p_stProtocolInterface->fn_uwStartBroadcastChannelScan= uwL0PCWin95ModemStartBroadcastChannelScan;
|
||
p_stProtocolInterface->fn_uwNextChannel= uwL0PCWin95ModemNextChannel;
|
||
p_stProtocolInterface->fn_uwNextBroadcastChannel= uwL0PCWin95ModemNextBroadcastChannel;
|
||
p_stProtocolInterface->fn_eReadData= eL0PCWin95SerialReadData;
|
||
p_stProtocolInterface->fn_eSendData= eL0PCWin95SerialSendData;
|
||
p_stProtocolInterface->fn_eQueryChannelStatus= eL0PCWin95SerialQueryChannelStatus;
|
||
p_stProtocolInterface->fn_vLevel0NetEngine = vL0PCWin95SerialNetEngine;
|
||
p_stProtocolInterface->fn_vCloseChannel = (tdfn_vCloseChannel)C_pNull;
|
||
p_stProtocolInterface->fn_vLevel0CloseProtocol = vL0PCWin95ModemCloseProtocol;
|
||
p_stProtocolInterface->eIsInternet = 0;
|
||
|
||
/* the channel array is initialized by the serial layer */
|
||
|
||
gs_bL0PCWin95ModemInitState = gs_bL0PCWin95ModemInitState | (char)0x01;
|
||
}
|
||
|
||
|
||
/*****************************************************************************
|
||
*
|
||
* Description: void vL0PCWin95ModemCloseProtocol();
|
||
*
|
||
* frees system resources used by the modem
|
||
*
|
||
*****************************************************************************
|
||
*
|
||
* Input: none
|
||
*
|
||
* Output: none
|
||
*
|
||
*****************************************************************************
|
||
* Creation Date: July 23, 1996 Author: Christophe ROGUET
|
||
*****************************************************************************
|
||
*
|
||
* Modification log:
|
||
*
|
||
* Date: Author:
|
||
* 8/11/96 Christophe Roguet
|
||
* moved some code from ExitTAPI() into this function
|
||
****************************************************************************/
|
||
void vL0PCWin95ModemCloseProtocol()
|
||
|
||
{
|
||
tduwNetChannel uwCurrentChannel;
|
||
|
||
if(lSerialChannelsOnceInitialized) {
|
||
/* close 'all' channels */
|
||
|
||
uwCurrentChannel=C_ModemSpecialChannel;
|
||
|
||
if( gs_a_stL0PCWin95SerialChannels[uwCurrentChannel].ubf1IsSlotInUse
|
||
&& gs_a_stL0PCWin95SerialChannels[uwCurrentChannel].ubf1IsSlotForModem
|
||
&& gs_a_stL0PCWin95SerialChannels[uwCurrentChannel].hCom!=INVALID_HANDLE_VALUE)
|
||
vL0PCWin95ModemCloseChannel(uwCurrentChannel);
|
||
|
||
/* release the critical sections used to synchronize channel access, */
|
||
/* as well as the communication overlapped operation structures */
|
||
|
||
if(gs_a_stL0PCWin95SerialChannels[uwCurrentChannel].ubf1IsSlotForModem) {
|
||
DeleteCriticalSection(&gs_a_stL0PCWin95SerialChannels[uwCurrentChannel].stChannelAccess);
|
||
CloseHandle(gs_a_stL0PCWin95SerialChannels[uwCurrentChannel].stOverlappedRead.hEvent);
|
||
CloseHandle(gs_a_stL0PCWin95SerialChannels[uwCurrentChannel].stOverlappedWrite.hEvent);
|
||
gs_a_stL0PCWin95SerialChannels[uwCurrentChannel].stOverlappedRead.hEvent=INVALID_HANDLE_VALUE;
|
||
gs_a_stL0PCWin95SerialChannels[uwCurrentChannel].stOverlappedWrite.hEvent=INVALID_HANDLE_VALUE;
|
||
}
|
||
} else
|
||
#ifdef NET_USE_DEBUG
|
||
vDebugFormat(Net_C_Debug_Modem, "pas de fermeture de canal");
|
||
#endif
|
||
|
||
vL0PCWin95ModemExitTAPI();
|
||
|
||
vLevel1RemoveProtocol(E_Net_pr_Windows95ModemProtocol);
|
||
}
|