/*---------------------------------------------------------------------------*
*
* BinkleyTerm
*
* (C) Copyright 1987-96, Bit Bucket Software Co.
* For license and contact information see /doc/orig_260/license.260.
*
* This version was modified by the BinkleyTerm XE Team.
* For contact information see /doc/team.lst and /doc/join.us.
* For a complete list of changes see /doc/xe_user.doc and /doc/xe_hist.doc.
*
* Filename : $Source: /cvsroot/btxe/btnt/sources/capi.cpp,v $
* Revision : $Revision: 1.1 $
* Tagname : $Name: $
* Last updated: $Date: 2005/01/01 15:18:12 $
* State : $State: Exp $
* Orig. Author: C.F.S.
*
* Description : CAPI-CID module
*
*---------------------------------------------------------------------------*/
#if defined(OS_2) && !defined(__EMX__)
#pragma stack16 (0)
#include "includes.h"
#include "third/capi11.h"
static HMODULE capiDLL = (HMODULE) 0;
HFILE IsdnHandle;
int ApplId;
int cancel;
static HEV EventSemaphore = 0;
int Manufacturer = 0;
bool needs_dossleep = FALSE;
void CAPIGoodBye (void);
char *MessageLost = "CAPI message lost";
char *BadID = "CAPI error: Invalid application ID";
#define MAN_UNKNOWN 0
#define MAN_DIEHL 1
#define MAN_TELES 2
#define MAN_NCP 3
#define MAN_NCPA 4
void
ConvertToDecent (unsigned char *number)
{
int i, j;
int l = number[0]; /* Length in [0], "nice" Pascal */
for (i = 1; i <= l; i++)
{
if (number[i] & 0x80)
break;
}
j = 0;
for (i++; i <= l; i++, j++)
number[j] = number[i];
number[j] = '\0';
}
void
#if defined(__IBMC__) || defined(__IBMCPP__)
ProcessCAPIMessage (void *msgrx)
#else
ProcessCAPIMessage (API_MSG _Far16 * msgrx)
#endif
{
API_MSG msg =
{
{0, 0, 0, 0}
};
API_MSG *apimsg = msgrx;
unsigned short cmx;
int plci, i, j;
unsigned char phone[40];
msg.header.Appl_id = ApplId;
msg.header.Number = 0;
if (apimsg == NULL) /* Null message */
return;
cmx = apimsg->header.Command;
switch (cmx)
{
case CONNECT_I:
plci = apimsg->info.connect_ind.PLCI;
i = apimsg->info.connect_ind.Structs[0];
for (j = 0; j <= i; j++)
phone[j] = apimsg->info.connect_ind.Structs[j];
phone[j] = 0;
ConvertToDecent (phone);
if (UpdateCID)
strcpy (CIDFromCAPI, (char *) phone);
msg.header.Length = 11;
msg.header.Command = CONNECT_I | RESPONSE;
msg.info.connect_res.PLCI = plci;
msg.info.connect_res.Reject = 1;
API_PUT_MESSAGE (ApplId, (API_MSG * _Seg16) & msg);
return;
case DISCONNECT_I:
plci = apimsg->info.disconnect_ind.PLCI;
msg.header.Length = 10;
msg.header.Command = DISCONNECT_I | CONFIRM;
msg.info.disconnect_res.PLCI = plci;
API_PUT_MESSAGE (ApplId, (API_MSG * _Seg16) & msg);
return;
/* Should not happen but just in case we are ready to process them */
case INFO_I:
plci = apimsg->info.info_ind.PLCI;
msg.header.Length = 10;
msg.header.Command = INFO_I | CONFIRM;
msg.info.info_con.PLCI = plci;
API_PUT_MESSAGE (ApplId, (API_MSG * _Seg16) & msg);
return;
}
return;
}
typedef void _Far16 _Pascal fnCapiSignal (void);
static void _Far16 _Pascal
SignalRoutine (void)
{
DosPostEventSem (EventSemaphore);
if (needs_dossleep)
DosSleep (1);
return;
}
void
Listen (PVOID x)
{
#ifdef __BORLANDC__
/* TE 140498: This probably is not correct, but it does not compile with
* Borland the other way round. You'd rather not use the CAPI
* feature with a Borland compiled BT ... */
API_MSG _Seg16 *msg;
#else
#if defined(__IBMC__) || defined(__IBMCPP__)
API_MSG *_Seg16 msg;
#else
API_MSG _Far16 *msg;
#endif
#endif
#if !defined(__IBMC__) && !defined(__IBMCPP__)
void _Far16 _Pascal (*pfnCapiSignal) (void);
#endif
int rcs, rca, i;
unsigned long scount = 0;
x = x;
#if !defined(__IBMC__) && !defined(__IBMCPP__)
pfnCapiSignal = &SignalRoutine;
#endif
printf ("CAPI message process thread successfully started.\n");
if (Manufacturer == MAN_NCPA)
{
do
{
DosSleep (5);
rca = API_GET_MESSAGE (ApplId, (API_MSG * _Seg16 * _Seg16) & msg);
if (rca == 0)
ProcessCAPIMessage (msg);
if (rca == 0x1002)
status_line (":%s (%d)", BadID, ApplId);
if (rca == 0x1007)
status_line (":%s", MessageLost);
}
while (!cancel);
_endthread ();
}
DosResetEventSem (EventSemaphore, &scount);
#if defined(__IBMC__) || defined(__IBMCPP__)
API_SET_SIGNAL (ApplId, SignalRoutine);
#else
API_SET_SIGNAL (ApplId, pfnCapiSignal);
#endif
if (Manufacturer == MAN_DIEHL)
{
do
{
rcs = DosWaitEventSem (EventSemaphore, 10000);
if (rcs == 0)
DosResetEventSem (EventSemaphore, &scount);
for (i = 0; i < scount; i++)
{
rca = API_GET_MESSAGE (ApplId, (API_MSG * _Seg16 * _Seg16) & msg);
if (rca == 0)
ProcessCAPIMessage (msg);
if (rca == 0x1002)
status_line (":%s (%d)", BadID, ApplId);
if (rca == 0x1007)
status_line (":%s", MessageLost);
};
}
while (!cancel);
_endthread ();
}
do
{
rcs = DosWaitEventSem (EventSemaphore, 10000);
if (rcs == 0)
DosResetEventSem (EventSemaphore, &scount);
do
{
rca = API_GET_MESSAGE (ApplId, (API_MSG * _Seg16 * _Seg16) & msg);
if (rca == 0)
ProcessCAPIMessage (msg);
if (rca == 0x1002)
status_line (":%s (%d)", BadID, ApplId);
if (rca == 0x1007)
status_line (":%s", MessageLost);
}
while (rca == 0);
}
while (!cancel);
_endthread ();
}
int
CAPISetup (char *eaz, char *services)
{
int rc;
char *MessageBuffer;
int NumberMessages, Layer3, L3Size, L3Packets;
char hb[100];
unsigned short EazMask = 0, ServiceMask = 0;
API_MSG msg =
{
{0, 0, 0, 0}
};
printf ("CAPI: ");
if (!API_INSTALLED ())
{
printf ("Not found. Cannot continue\n");
return -1;
}
printf ("is installed.\n");
printf ("Manufacturer: ");
API_GET_MANUFACTURER (hb);
printf ("%s\n", hb);
Manufacturer = MAN_UNKNOWN;
if (strstrci (hb, "Diehl") == hb)
Manufacturer = MAN_DIEHL;
if (strstrci (hb, "TELES") == hb)
Manufacturer = MAN_TELES;
if (strstrci (hb, "High So") == hb)
Manufacturer = MAN_NCP;
if (strstrci (hb, "NCP") == hb)
Manufacturer = MAN_NCPA;
API_GET_VERSION (hb);
printf ("Version: %s\n", hb);
if (strstr (hb, "Release 2.9") != NULL && Manufacturer == MAN_TELES)
needs_dossleep = TRUE;
API_GET_SERIAL_NUMBER (hb);
printf ("Serial #: %s\n", hb);
/* ------------------------- Variable setup ---------------------------- */
MessageBuffer = (char *) malloc (65000L);
if (MessageBuffer == NULL)
{
printf ("Not enough memory for message buffer.\n");
return -1;
}
NumberMessages = 40;
Layer3 = 2;
L3Size = 2048;
if (Manufacturer == MAN_DIEHL)
L3Packets = (63000 - (180 * NumberMessages)) / L3Size;
else
L3Packets = (32000 - (180 * NumberMessages)) / L3Size;
/* ---------------------- Registration with CAPI ---------------------- */
ApplId = 0;
ApplId = API_REGISTER (MessageBuffer, NumberMessages, Layer3, L3Packets, L3Size);
if (!ApplId)
{
printf ("CAPI registration failed.\n");
return -1;
}
printf ("Registration with CAPI successful (ID: %d)\n", ApplId);
rc = DosCreateEventSem ((PSZ) NULL, &EventSemaphore, 0, FALSE);
if (rc)
{
printf ("\nError calling DosCreateEventSem: %d\n", rc);
CAPIGoodBye ();
return -1;
}
cancel = 0;
_beginthread (Listen, NULL, 32768, NULL);
DosSleep (1000); /* Sleep a bit until CAPI is ready */
msg.header.Length = 17;
msg.header.Command = LISTEN_R;
msg.header.Appl_id = ApplId;
msg.info.listen_req.Controller = 0;
msg.info.listen_req.Info_Mask = 0x0000; /* Don't disturb with infos */
msg.info.listen_req.Si_Mask = 0x000F; /* Mask */
while (isdigit (*eaz))
EazMask |= (0x01 << (*eaz++ & 0x0F));
while (*services)
{
switch (toupper (*services++))
{
case 'V':
ServiceMask |= 1;
break;
case 'T':
ServiceMask |= 2;
break;
case 'A':
ServiceMask |= 4;
break;
case '2':
ServiceMask |= 8;
break;
case '4':
ServiceMask |= 16;
break;
case 'I':
ServiceMask |= 32;
break;
case 'D':
ServiceMask |= 128;
break;
case '5':
ServiceMask |= 256;
break;
case 'L':
ServiceMask |= 512;
break;
case 'M':
ServiceMask |= 1024;
break;
case 'R':
ServiceMask |= 8192;
break;
case 'G':
ServiceMask |= 16384;
break;
case 'X':
ServiceMask |= 32768;
break;
}
}
printf ("EAZ Mask: %hu, Service Mask %hu\n", EazMask, ServiceMask);
msg.info.listen_req.Eaz_Mask = EazMask;
msg.info.listen_req.Si_Mask = ServiceMask;
rc = API_PUT_MESSAGE (ApplId, (API_MSG *) & msg);
return 0;
}
void
CAPIGoodBye (void)
{
int rc = API_RELEASE (ApplId);
cancel = 1;
if (!rc)
printf ("Capi released successfully.\n");
else
printf ("Could not release CAPI (error: %d)!\n", rc);
DosSleep (100);
}
USHORT
CapiLoadDLL (void)
{
APIRET rc = 0;
rc = DosLoadModule (NULL, 0l, (PCSZ) "CAPI", &capiDLL);
if (rc == 0)
{
rc += BtQueryProcAddr (capiDLL, 0L, (PCSZ) "API_REGISTER",
(PFN *) & API_REGISTER);
rc += BtQueryProcAddr (capiDLL, 0L, (PCSZ) "API_RELEASE",
(PFN *) & API_RELEASE);
rc += BtQueryProcAddr (capiDLL, 0L, (PCSZ) "API_GET_MESSAGE",
(PFN *) & API_GET_MESSAGE);
rc += BtQueryProcAddr (capiDLL, 0L, (PCSZ) "API_PUT_MESSAGE",
(PFN *) & API_PUT_MESSAGE);
rc += BtQueryProcAddr (capiDLL, 0L, (PCSZ) "API_SET_SIGNAL",
(PFN *) & API_SET_SIGNAL);
rc += BtQueryProcAddr (capiDLL, 0L, (PCSZ) "API_GET_MANUFACTURER",
(PFN *) & API_GET_MANUFACTURER);
rc += BtQueryProcAddr (capiDLL, 0L, (PCSZ) "API_GET_VERSION",
(PFN *) & API_GET_VERSION);
rc += BtQueryProcAddr (capiDLL, 0L, (PCSZ) "API_INSTALLED",
(PFN *) & API_INSTALLED);
rc += BtQueryProcAddr (capiDLL, 0L, (PCSZ) "API_GET_SERIAL_NUMBER",
(PFN *) & API_GET_SERIAL_NUMBER);
}
return (USHORT) rc;
}
void
CapiUnLoadDLL (void)
{
if (capiDLL)
DosFreeModule (capiDLL);
}
USHORT
CapiInstalled (void)
{
return (API_INSTALLED ());
}
int
CAPIInit (char *EAZs, char *Services)
{
int x;
printf ("----------------------------------------------\n");
if (CapiLoadDLL ())
{
printf ("Link with CAPI failed, CAPI.DLL not found?\n");
return -1;
}
x = CAPISetup (EAZs, Services);
printf ("----------------------------------------------\n");
return x;
}
void
CAPIStop (void)
{
UseCAPICID = 0;
CAPIGoodBye ();
CapiUnLoadDLL ();
}
#endif /* if defined(OS_2) && !defined(__EMX__) */
/* $Id: capi.cpp,v 1.1 2005/01/01 15:18:12 vildanov Exp $ */