📄 connect.c
字号:
des_set_key((des_cblock *) (((protocolSent == PROTOCOL_RTP) ?
pClientData->rtpdeskey : pClientData->vatdeskey) + 1), sched);
des_ncbc_encrypt((des_cblock *) aux,
(des_cblock *) aux, msgl, sched,
(des_cblock *) ivec, DES_ENCRYPT);
msg = aux;
}
#endif
if (pClientData->localLoopback) {
stat = loop_sendto(pClientData, msg, msgl,
(LPSOCKADDR) &(pClientData->ctrl), sizeof pClientData->ctrl);
} else {
if ((!useSendNotSendto || waNetNoConnect) && (!waNetUseSend)) {
stat = sendto(pClientData->sControl, msg, msgl, 0,
(LPSOCKADDR) &(pClientData->ctrl), sizeof pClientData->ctrl);
if (stat < 0) {
if (!waNetNoConnect) {
useSendNotSendto = TRUE;
if (hDlgPropeller != NULL) {
SetDlgItemText(hDlgPropeller, IDC_PH_SENDTO, rstring(IDS_T_SEND));
}
}
}
}
/* Careful! Don't "optimise" this to "else if"; we have to be
able to switch-hit when the first sendto() fails above. */
if (useSendNotSendto) {
stat = send(pClientData->sControl, msg, msgl, 0);
}
}
propeller(IDC_PH_PACKETS_SENT, ++packetsSent);
}
/* CREATESOUNDBUFFER -- Create a standard format sound buffer
with selected compression modes from a
set of raw samples received from the audio
input port. Special gimmick: align==0 means
the data are already in place in mu-law
encoding (rate==8000 only). This allows fast
processing of mu-law encoded sound files. */
void createSoundBuffer(LPSTR buffer, WORD buflen, DWORD channels,
DWORD rate, DWORD bytesec, WORD align)
{
int knownFormat = FALSE;
// If the spectrum display is open, let it see the raw samples
spectrumUpdate(buffer, buflen, channels, rate, bytesec, align, FALSE);
if (rate == 8000) {
if (align == 2) {
LONG i;
int j;
for (i = j = 0; i < (LONG) buflen / align; i++) {
sb.buffer.buffer_val[j++] = audio_s2u((((WORD *) buffer)[i]));
}
} else if (align == 1) { // align == 1
LONG i;
int j;
for (i = j = 0; i < (LONG) buflen; i++) {
sb.buffer.buffer_val[j++] = audio_c2u((((BYTE *) buffer)[i]));
}
} else { // (align == 0) already stored in mu-law encoding
align = 1;
}
sb.buffer.buffer_len = buflen / align;
knownFormat = TRUE;
} else if (rate == 11025 && align == 2) {
LONG i;
int j, k;
for (i = j = k = 0; i < (LONG) (buflen / align); i++) {
if ((k & 3) != 2 && ((i % 580) != 579)) {
sb.buffer.buffer_val[j++] = audio_s2u((((WORD *) buffer)[i]));
}
k = (k + 1) % 11;
}
sb.buffer.buffer_len = j;
knownFormat = TRUE;
} else if (rate == 11025 && align == 1) {
LONG i;
int j, k;
for (i = j = k = 0; i < (LONG) (buflen / align); i++) {
if ((k & 3) != 2 && ((i % 580) != 579)) {
sb.buffer.buffer_val[j++] = audio_c2u((((BYTE *) buffer)[i]));
}
k = (k + 1) % 11;
}
sb.buffer.buffer_len = j;
knownFormat = TRUE;
}
sqpacket = FALSE;
if (knownFormat) {
if (voxmode != IDM_VOX_NONE) {
LONG i;
long alevel = 0;
static long voxSampleCountdown;
int j, thresh;
thresh = (int) exp(log(32767.0) * ((1000 - noise_threshold) / 1000.0));
for (i = 0, j = 0; i < sb.buffer.buffer_len; i++, j++) {
int samp = audio_u2s(sb.buffer.buffer_val[j]);
if (samp < 0) {
samp = -samp;
}
alevel += samp;
}
alevel /= sb.buffer.buffer_len;
//{char s[132]; sprintf(s, "Nt = %d, Thresh = %d, Max = %d, Alevel = %ld, VU = %.2g\r\n",
//noise_threshold, thresh, maxsamp, alevel,
//log((double) alevel) / log(32767.0)); OutputDebugString(s);}
voxMonitorUpdate(alevel, 0);
if (alevel < thresh) {
if (voxSampleCountdown <= 0) {
sqpacket = TRUE;
sb.buffer.buffer_len = 0;
return;
}
voxSampleCountdown -= sb.buffer.buffer_len;
} else {
switch (voxmode) {
case IDM_VOX_FAST:
voxSampleCountdown = 4000;
break;
case IDM_VOX_MEDIUM:
voxSampleCountdown = 8000;
break;
case IDM_VOX_SLOW:
voxSampleCountdown = 12000;
break;
}
}
}
if (compression) {
compress2X(&sb);
}
if (gsmcompress) {
gsmcomp(&sb);
}
if (adpcmcompress) {
// Sledgehammer to verify that lockup-prevention code works OK
//long l; l = GetTickCount();
//while (GetTickCount() - l < 350) ;
adpcmcomp(&sb);
}
if (lpccompress) {
lpccomp(&sb);
}
if (lpc10compress) {
lpc10comp(&sb);
}
if (celpcompress) {
celpcomp(&sb);
}
pktlen = sb.buffer.buffer_len + (sizeof(struct soundbuf) - BUFL);
// Ugly, ugly ugly. RTP and VAT need compression modes here.
sb.compression = fProtocol;
sb.compression |= gsmcompress ? fCompGSM : 0;
sb.compression |= adpcmcompress ? fCompADPCM : 0;
sb.compression |= lpccompress ? fCompLPC : 0;
if (protocolSent == PROTOCOL_RTP) {
pktlen = rtpout(&sb, ssrc, timestamp, seq, spurt);
seq++;
timestamp += currentInputSamples;
} else if (protocolSent == PROTOCOL_VAT) {
pktlen = vatout(&sb, 0L, timestamp, spurt);
timestamp += currentInputSamples;
}
spurt = FALSE; /* Not the start of a talk spurt */
}
}
/* CREATENEWCONNECTION -- Create a new connection MDI window. */
HWND createNewConnection(LPCLIENT_DATA pClientData)
{
MDICREATESTRUCT mcs;
HWND hwnd;
SOCKERR serr = 0;
int vover;
#ifdef TRACE_FACE
OutputDebugString("createNewConnection()\r\n");
#endif
vover = (GetSystemMetrics(SM_CYFRAME) * 2) + GetSystemMetrics(SM_CYCAPTION) - 1;
mcs.szClass = pszClientClass;
mcs.szTitle = pClientData->localLoopback ?
rstring(IDS_T_LOOPBACK) : pClientData->szHost,
mcs.hOwner = hInst;
mcs.x = CW_USEDEFAULT;
mcs.y = CW_USEDEFAULT;
mcs.cx = tmAveCharWidth * 50;
mcs.cy = ((4 * tmHeight) + 5) + vover;
mcs.style = 0;
hwnd = FORWARD_WM_MDICREATE(hwndMDIClient, (LPMDICREATESTRUCT) &mcs, SendMessage);
if (hwnd == NULL) {
return NULL;
}
pClientData->state = Idle;
SetWindowLong(hwnd, GWL_CLIENT, (LONG) pClientData);
if (!pClientData->modemConnection) {
serr = CreateSocket(&(pClientData->sReply), SOCK_DGRAM,
htonl(INADDR_ANY), 0);
if (serr == 0) {
#ifdef ASYNC_OUTPUT
if (WSAAsyncSelect(pClientData->sReply, hwnd, WM_SOCKET_SELECT, FD_WRITE) != 0) {
serr = WSAGetLastError();
}
#endif
if (serr == 0) {
pClientData->name.sin_family = PF_INET;
pClientData->name.sin_addr = pClientData->inetSock.sin_addr;
pClientData->name.sin_port = htons(pClientData->port);
if (!waNetNoConnect) {
if (connect(pClientData->sReply, (LPSOCKADDR) &(pClientData->name),
sizeof(pClientData->name)) != 0) {
serr = WSAGetLastError();
}
}
}
}
if (serr != 0) {
MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(23),
(LPSTR) pClientData->szHost, serr, SockerrToString(serr));
return NULL;
}
// Create control socket for RTP and VAT protocol connections
serr = CreateSocket(&(pClientData->sControl), SOCK_DGRAM,
htonl(INADDR_ANY), 0);
if (serr == 0) {
#ifdef ASYNC_OUTPUT
if (WSAAsyncSelect(pClientData->sReply, hwnd, WM_SOCKET_CONTROL, FD_WRITE) != 0) {
serr = WSAGetLastError();
}
#endif
if (serr == 0) {
pClientData->ctrl.sin_family = PF_INET;
pClientData->ctrl.sin_addr = pClientData->inetSock.sin_addr;
pClientData->ctrl.sin_port = htons((short) (pClientData->port + 1));
if (!waNetNoConnect) {
if (connect(pClientData->sControl, (LPSOCKADDR) &(pClientData->ctrl),
sizeof(pClientData->ctrl)) != 0) {
serr = WSAGetLastError();
}
}
}
}
if (serr != 0) {
MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(67),
(LPSTR) pClientData->szHost, serr, SockerrToString(serr));
return NULL;
}
/* If this is a nonstandard port, create auxiliary sockets to
receive input from that port. */
if (pClientData->port != NETFONE_COMMAND_PORT) {
pClientData->auxSock = monitorPort(pClientData->port);
}
}
pClientData->gsmh = gsm_create();
pClientData->rseq = -1; // Initialise receive sequence number
rate_start(&pClientData->rateconv, 4000, 8000); // Initialise 2X decompression
/* Save the sending host for Speak Freely protocol packets. */
{
char gh[MAX_HOST];
gethostname(gh, sizeof gh);
if (strlen(gh) > ((sizeof ourSendingHost) - 1)) {
gh[(sizeof ourSendingHost) - 1] = 0;
}
strcpy(ourSendingHost, gh);
strcpy(sb.sendinghost, ourSendingHost);
}
#ifdef MODEM
if (pClientData->modemConnection) {
SetWindowText(hwnd, rstring(IDS_T_MODEM_CONNECTION));
modemSessions++;
} else
#endif
if (pClientData->szHost[0] == '(' && !pClientData->localLoopback) {
/* I'm sure by now you're shocked and stunned to discover that
some Winsock implementations, Sun PC-NFS 5.1, to name one,
don't correctly implement the WSAAsyncGetHostByAddr function.
Oh, you can make the call, and you even get back a valid host
name. But doing so plants a time bomb which will kill you
(at least under the debug kernel) much, much later when you call
WSACleanup() right before exiting the program. At that time,
depending on where the random pointer inside their so-called
WSHELPER points, you get either two invalid global pointer
errors or a fatal error due to an object usage count underflow in the
(bogus) global block. If the waNetSynchronousGetHostnameAction is
set, we eschew the asynchronous request and make the user
wait for a blocking gethostbyaddr() which has the merit, at
least, of not blowing us away at program termination time. */
if (!waNetSynchronousGetHostnameAction) {
/* This is a temporary connection initiated from the remote site.
Schedule a lookup to obtain the full domain name of the host,
not just the hostname included in the sound packet. */
pClientData->getNameTask = WSAAsyncGetHostByAddr(hwnd, WM_SOCKET_ASYNC,
(CHAR *) &pClientData->inetSock.sin_addr,
sizeof(pClientData->inetSock.sin_addr),
PF_INET, pClientData->hostBuffer,
sizeof(pClientData->hostBuffer));
if (pClientData->getNameTask == NULL) {
int serr = WSAGetLastError();
MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(24),
(LPSTR) pClientData->szHost, serr, SockerrToString(serr));
}
} else{
LPHOSTENT h = gethostbyaddr((CHAR *) &pClientData->inetSock.sin_addr,
sizeof(pClientData->inetSock.sin_addr),
PF_INET);
if (h == NULL) {
#ifdef SHOW_GET_HOST_NAME_ERROR
int serr = WSAGetLastError();
MsgBox(hwnd, MB_ICONSTOP | MB_OK, Format(27),
pClientData->szHost, serr,
SockerrToString(serr));
#endif
} else {
strcpy(pClientData->szHost, h->h_name);
SetWindowText(hwnd, pClientData->localLoopback ?
rstring(IDS_T_LOOPBACK) : pClientData->szHost);
changeAudioState(hwnd, pClientData);
}
pClientData->getNameTask = NULL;
}
}
DragAcceptFiles(hwnd, TRUE);
ShowWindow(hwnd, SW_SHOW);
openConnections++;
propUpdateAudio();
updateTrayToolTipText();
return hwnd;
}
// CONNFETCHFACE -- Begin retrieval of a face image.
void connFetchFace(HWND hwndClient, LPCLIENT_DATA pClientData)
{
// pClientData->face_stat = FSabandoned;
// if (pClientData->face_stat != -1) {
#ifdef TRACE_FACE
OutputDebugString("connFetchFace()\r\n");
#endif
pClientData->face_address = 0L;
pClientData->face_timeout = 0;
pClientData->face_retry = 0;
pClientData->face_stat = FSreply; // Activate request from timeout
SetTimer(hwndClient, 5, (UINT) FaceFetchInterval, NULL);
// }
}
// STARTSOUNDFILE -- Begin playing a sound file.
VOID startSoundFile(HWND hwnd, LPSTR pszFile)
{
LPCLIENT_DATA pClientData;
HFILE hFile = HFILE_ERROR;
char magic[4];
pClientData = CLIENTPTR(hwnd);
pClientData->quitSoundFile = FALSE;
pClientData->hFile = HFILE_ERROR;
if (pClientData->timeout > 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -