📄 connect.c
字号:
/*
Window procedure for connection MDI window
*/
#include "netfone.h"
#define ASYNC_OUTPUT
static struct {
char header[4];
unsigned short len, ilen;
soundbuf sbm;
} mb = {{1, 2, 3, 4}};
#define sb mb.sbm
soundbuf ebuf; // Utility sound buffer
static LONG pktlen; // Packet length to transmit
static struct adpcm_state adpcm; // ADPCM compression state
static int squelched = FALSE; // Squelched by VOX ?
static int sqpacket = FALSE; // Is this packet squelched
static char ourSendingHost[16]; // Host name for sound buffer sendinghost
static int xseq = 0; // Robust mode transmit sequence number
extern long outputPending;
char blankit[] = " "
" "
" ";
/* GSMCOMP -- Compress the contents of a sound buffer using GSM. */
static void gsmcomp(soundbuf *asb)
{
gsm_signal src[160];
gsm_frame dst;
int i, j, l = 0;
char *dp = (asb->buffer.buffer_val) + sizeof(short);
long ldata = asb->buffer.buffer_len;
for (i = 0; i < ldata; i += 160) {
for (j = 0; j < 160; j++) {
if ((i + j) < asb->buffer.buffer_len) {
src[j] = audio_u2s(asb->buffer.buffer_val[i + j]);
} else {
src[j] = 0;
}
}
gsm_encode(gsmh, src, dst);
_fmemcpy(dp, dst, sizeof dst);
dp += sizeof dst;
l += sizeof dst;
}
/* Hide original uncompressed buffer length in first 2 bytes of buffer. */
*((short *) asb->buffer.buffer_val) = (short) ldata;
revshort((short *) asb->buffer.buffer_val);
asb->buffer.buffer_len = l + sizeof(short);
}
/* ADPCMCOMP -- Compress the contents of a sound buffer using ADPCM. */
static void adpcmcomp(soundbuf *asb)
{
unsigned char *dp = (unsigned char *) asb->buffer.buffer_val;
struct adpcm_state istate;
istate = adpcm;
adpcm_coder_u(dp, (char *) dp, (int) asb->buffer.buffer_len, &adpcm);
asb->buffer.buffer_len /= 2;
/* Hide the ADPCM encoder state at the end of this buffer.
The shifting and anding makes the code byte-order
insensitive. */
dp += asb->buffer.buffer_len;
*dp++ = ((unsigned int) istate.valprev) >> 8;
*dp++ = istate.valprev & 0xFF;
*dp = istate.index;
asb->buffer.buffer_len += 3;
}
/* LPCCOMP -- Compress the contents of a sound buffer using LPC. */
static void lpccomp(asb)
soundbuf *asb;
{
int i, l = 0;
char *dp = ((char *) asb->buffer.buffer_val) + sizeof(short);
unsigned char *src = ((unsigned char *) asb->buffer.buffer_val);
lpcparams_t lp;
asb->compression |= fCompLPC;
for (i = 0; i < asb->buffer.buffer_len; i += LPC_FRAME_SIZE) {
lpc_analyze(src + i, &lp);
_fmemcpy(dp, &lp, sizeof lp);
dp += sizeof lp;
l += sizeof lp;
}
// Hide original uncompressed buffer length in first 2 bytes of buffer.
*((short *) asb->buffer.buffer_val) = (short) asb->buffer.buffer_len;
revshort((short *) asb->buffer.buffer_val);
asb->buffer.buffer_len = l + sizeof(short);
}
/* LPC10COMP -- Compress the contents of a sound buffer using LPC-10. */
static void lpc10comp(soundbuf *asb)
{
char *dp = (char *) asb->buffer.buffer_val;
unsigned char *src = ((unsigned char *) asb->buffer.buffer_val);
asb->compression |= fCompLPC10;
asb->buffer.buffer_len = lpc10encode(src, dp, asb->buffer.buffer_len);
}
/* LPC10STUFF -- Stuff last 16 bytes of LPC10 packet in sendinghost. */
static int lpc10stuff(struct soundbuf FAR *asb, int pktlen)
{
if ((asb->compression & fCompLPC10) && (asb->buffer.buffer_len > 16)) {
_fmemcpy(asb->sendinghost,
((char *) asb) + (pktlen - (sizeof asb->sendinghost)),
sizeof asb->sendinghost);
pktlen -= sizeof asb->sendinghost;
if (robust > 1) {
asb->compression |= fCompRobust;
asb->buffer.buffer_len |= ((long) xseq) << 24;
xseq = (xseq + 1) & 0xFF;
}
}
return pktlen;
}
/* LPC10UNSTUFF -- Reverse the effect of lpc10stuff. */
static void lpc10unstuff(struct soundbuf FAR *asb)
{
if ((asb->compression & fCompLPC10) && (asb->buffer.buffer_len > 16)) {
pktlen += sizeof asb->sendinghost;
if (asb->compression & fCompRobust) {
asb->compression &= ~fCompRobust;
asb->buffer.buffer_len &= 0xFFFFFFL;
}
}
}
/* COMPRESS2X -- Compress a sound buffer with Simple (discard every
other sample) compression. If you're doing both
Simple and GSM compression, Simple compression must be
done first. */
void compress2X(soundbuf *asb)
{
#ifdef OLD2X
LONG i;
asb->buffer.buffer_len /= 2;
for (i = 1; i < asb->buffer.buffer_len; i++) {
asb->buffer.buffer_val[i] = asb->buffer.buffer_val[i * 2];
}
#else
int li = (int) asb->buffer.buffer_len;
int lo = li / 2;
rate_flow(&xrate, (unsigned char *) asb->buffer.buffer_val,
(unsigned char *) asb->buffer.buffer_val,
&li, &lo);
asb->buffer.buffer_len = lo;
#endif
}
/* MONITORPORT -- Obtain an auxiliary socket to receive input
from a given port. Existing sockets are reused
and their reference count incremented. */
static struct auxSocket FAR *monitorPort(unsigned short port)
{
struct auxSocket FAR *as = asList;
WORD serr = 0;
while (as != NULL) {
if (port == as->asport) {
break;
}
as = as->asnext;
}
if (as == NULL) {
#ifdef TRACE_AUX_SOCKET
OutputDebugString("Allocating aux socket.\r\n");
#endif
as = (struct auxSocket FAR *) GlobalAllocPtr(GPTR, sizeof(struct auxSocket));
if (as != NULL) {
as->asnext = asList;
asList = as;
as->asrefc = 0;
as->asport = port;
as->asdata = as->asctrl = INVALID_SOCKET;
}
}
if (as != NULL) {
if (as->asrefc == 0) {
serr = CreateSocket(&(as->asdata), SOCK_DGRAM,
htonl(INADDR_ANY), htons(as->asport));
if (serr != 0) {
MsgBox(NULL, MB_ICONSTOP | MB_OK, Format(73),
port, serr, SockerrToString(serr));
goto bang;
}
serr = CreateSocket(&(as->asctrl), SOCK_DGRAM,
htonl(INADDR_ANY), htons((short) (as->asport + 1)));
if (serr != 0) {
MsgBox(NULL, MB_ICONSTOP | MB_OK, Format(73),
port + 1, serr, SockerrToString(serr));
goto bang;
}
#ifdef ASYNC_OUTPUT
if (WSAAsyncSelect(as->asdata, hwndMDIFrame, WM_SOCKET_SELECT, FD_READ) != 0) {
serr = WSAGetLastError();
}
if (serr != 0) {
MsgBox(NULL, MB_ICONSTOP | MB_OK, Format(73),
port, serr, SockerrToString(serr));
goto bang;
}
if (WSAAsyncSelect(as->asctrl, hwndMDIFrame, WM_SOCKET_CONTROL, FD_READ) != 0) {
serr = WSAGetLastError();
}
if (serr != 0) {
MsgBox(NULL, MB_ICONSTOP | MB_OK, Format(73),
port + 1, serr, SockerrToString(serr));
goto bang;
}
#endif
#ifdef TRACE_AUX_SOCKET
OutputDebugString("Opened aux socket.\r\n");
#endif
#ifdef IP_MAX_MEMBERSHIPS
multicastJoin(hwndMDIFrame, FALSE);
multicastJoin(hwndMDIFrame, TRUE);
#endif
}
as->asrefc++;
}
return as;
bang:
if (as->asdata != INVALID_SOCKET) {
closesocket(as->asdata);
as->asdata = INVALID_SOCKET;
}
if (as->asctrl != INVALID_SOCKET) {
closesocket(as->asctrl);
as->asctrl = INVALID_SOCKET;
}
return NULL;
}
// WRITEOUTPUT -- Transmit output buffer to destination
static int writeOutput(LPCLIENT_DATA d, LPSTR buf, int buflen)
{
#ifdef MODEM
if (d->modemConnection) {
if (modemHandle != -1) {
unsigned short bcrc;
COMSTAT cs;
int wrl, err;
mb.len = (unsigned short) buflen;
mb.ilen = ~mb.len;
revshort(&mb.len);
revshort(&mb.ilen);
bcrc = crc((LPSTR) &mb, buflen + 4 + 2 * sizeof(unsigned short));
revshort(&bcrc);
err = GetCommError(modemHandle, &cs);
if (err != 0) {
MsgBox(hwndMDIFrame, MB_ICONSTOP | MB_OK, Format(20), err);
errorRant(hwndMDIFrame);
return -1;
}
wrl = WriteComm(modemHandle, &mb, buflen + 4 + 2 * sizeof(unsigned short));
err = GetCommError(modemHandle, &cs);
if (err != 0) {
MsgBox(hwndMDIFrame, MB_ICONSTOP | MB_OK, Format(21), err);
errorRant(hwndMDIFrame);
return -1;
}
if (wrl > 0) {
wrl = WriteComm(modemHandle, &bcrc, sizeof(short));
}
err = GetCommError(modemHandle, &cs);
if (err != 0) {
MsgBox(hwndMDIFrame, MB_ICONSTOP | MB_OK, Format(22), err);
errorRant(hwndMDIFrame);
return -1;
}
return buflen;
}
} else
#endif
if (d->outputSocketBusy) {
propeller(IDC_PH_OUTPUT_LOST, ++outputPacketsLost);
#ifdef OVERLOAD
OutputDebugString("Socket busy--packet discarded.\r\n");
#endif
return buflen;
} else {
int stat, wasSentTo = FALSE;
#ifdef OVERLOAD
int OL;
for (OL = 0; OL < OVERLOAD; OL++) {
#endif
if (d->localLoopback || ((!useSendNotSendto || waNetNoConnect) &&
(!waNetUseSend))) {
if (d->localLoopback) {
stat = loop_sendto(d, buf, buflen,
(LPSOCKADDR) &(d->name), sizeof d->name);
} else {
stat = sendto(d->sReply, buf, buflen, 0,
(LPSOCKADDR) &(d->name), sizeof d->name);
}
if (stat < 0) {
if (!waNetNoConnect) {
useSendNotSendto = TRUE;
if (hDlgPropeller != NULL) {
SetDlgItemText(hDlgPropeller, IDC_PH_SENDTO, rstring(IDS_T_SEND));
}
}
} else {
wasSentTo = TRUE;
}
}
/* Careful! Don't "optimise" this to "else if"; we have to be
able to switch-hit when the first sendto() fails above. */
if (!wasSentTo) {
stat = send(d->sReply, buf, buflen, 0);
}
if (stat == buflen) {
propeller(IDC_PH_PACKETS_SENT, ++packetsSent);
#ifdef OVERLOAD
if ((rand() & 0x3F) == 0) { d->outputSocketBusy = TRUE; OutputDebugString("Dooooh!\r\n"); }
#endif
} else {
propeller(IDC_PH_OUTPUT_LOST, ++outputPacketsLost);
if (!waNetNoOutOverflow) {
/* Great leap of faith. Treat a "WSAEWOULDBLOCK" error as
a truncated buffer and do nothing other than mark the
socket busy. */
d->outputSocketBusy = TRUE;
if (stat == SOCKET_ERROR &&
WSAGetLastError() == WSAEWOULDBLOCK) {
stat = 0;
}
}
#ifdef OVERLOAD
OutputDebugString("Socket write failed.\r\n");
#endif
}
#ifdef OVERLOAD
}
#endif
return stat;
}
}
// SOCKETERRORBOX -- Show message box for socket error
static void socketerrorbox(HWND hwnd, LPCLIENT_DATA d)
{
if (d->modemConnection) {
MessageBox(hwnd, rstring(IDS_T_MODEM_WRITE_ERR), NULL,
MB_ICONEXCLAMATION | MB_OK);
} else {
MessageBox(hwnd, SockerrToString(WSAGetLastError()), rstring(IDS_T_SOCKET_WRITE_ERR),
MB_ICONEXCLAMATION | MB_OK);
}
}
/* SENDPKT -- Send a message to the destination. */
static int sendpkt(HWND hwnd, LPCLIENT_DATA d, struct soundbuf *asb)
{
LONG lts = asb->buffer.buffer_len;
LONG pkl = pktlen;
struct soundbuf *osb = asb;
#ifdef CRYPTO
if ((d->deskey[0] || d->ideakey[0] || d->opgpkey[0] ||
d->blowfish_spec || d->otpFileName[0])) {
int i;
LONG slen;
_fmemcpy(&ebuf, asb, (int) pktlen);
slen = lts;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -