⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 connect.c

📁 IP网络语音通讯软件源代码. 不可多得的语音源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        osb = &ebuf;

        /* DES encryption. */

        if (d->deskey[0]) {
			if (protocolSent == PROTOCOL_RTP || protocolSent == PROTOCOL_VAT) {
				LONG vlen = pktlen;
				des_key_schedule sched;
				des_cblock ivec;

                /* If we're DES encrypting we must round the size of
				   the data to be sent to be a multiple of 8 so that
				   the entire DES frame is sent.  If this is an RTP
				   packet, we may have to set the Pad bit in the
				   header and include a count of pad bytes at the end
				   of the packet. */

				_fmemset(ivec, 0, 8);
				pkl = (pktlen + 7) & (~7);
				if (pkl > pktlen) {
					_fmemset(((char *) &ebuf) + vlen, 0, (int) (pkl - vlen));
				}
				if ((protocolSent == PROTOCOL_RTP) && (pkl > vlen)) {
					char *p = (char *) &ebuf;

					p[0] |= 0x20; /* Set pad bytes present bit */
					p[pkl - 1] = (unsigned char) (pkl - vlen); /* Set pad count at end */
				}
				des_set_key((des_cblock FAR *) (((protocolSent == PROTOCOL_RTP) ? d->rtpdeskey :
								d->vatdeskey) + 1), sched);
				des_ncbc_encrypt((des_cblock *) &ebuf,
					(des_cblock *) &ebuf, pkl, sched,
					(des_cblock *) ivec, DES_ENCRYPT);
				slen = pkl - (sizeof(struct soundbuf) - BUFL); 
			} else {
	        	char twibble[8];
	        	
	        	_fmemcpy(twibble, d->deskey + 1, 8);
	            setkey(twibble);
	
	            /* If we're DES encrypting we must round the size of
	               the data to be sent to be a multiple of 8 so that
	               the entire DES frame is sent. */
	
	            slen = (slen + 7) & (~7);
	            for (i = 0; i < slen; i += 8) {
	
	                /* Apply cipher block chaining within the packet. */
	
	                if (i > 0) {
	                    int j;
	
	                    for (j = 0; j < 8; j++) {
	                        ebuf.buffer.buffer_val[(i + j)] ^=
	                            ebuf.buffer.buffer_val[(i + j) - 8];
	                    }
	                }
	                endes(ebuf.buffer.buffer_val + i);
	            }
	            ebuf.compression |= fEncDES;
	        }
        }

        /* IDEA encryption. */

        if ((protocolSent == PROTOCOL_SPEAKFREE) && d->ideakey[0]) {
            unsigned short iv[4];
	        char twibble[16];
	        
	        _fmemcpy(twibble, d->ideakey + 1, 16);
            memset(iv, 0, sizeof(iv));
            initcfb_idea(iv, twibble, FALSE);

            /* If we're IDEA encrypting we must round the size of
               the data to be sent to be a multiple of 8 so that
               the entire IDEA frame is sent. */

            slen = (slen + 7) & (~7); 
            ideacfb(ebuf.buffer.buffer_val, (int) slen);
            close_idea();
            ebuf.compression |= fEncIDEA;
        }

        /* Blowfish encryption. */

        if ((protocolSent == PROTOCOL_SPEAKFREE) && d->blowfish_spec) {
            unsigned char iv[8];
	        
            memset(iv, 0, sizeof(iv));

            /* If we're Blowfish encrypting we must round the size of
               the data to be sent to be a multiple of 8 so that
               the entire Blowfish frame is sent. */

            slen = (slen + 7) & (~7); 
            BF_cbc_encrypt((unsigned char *) ebuf.buffer.buffer_val,
						   (unsigned char *) ebuf.buffer.buffer_val,
						   slen, &(d->blowfishkey), iv, BF_ENCRYPT);
            ebuf.compression |= fEncBF;
        }

        /* PGP session key encryption. */

        if ((protocolSent == PROTOCOL_SPEAKFREE) && d->opgpkey[0]) {
            unsigned short iv[4];
	        char twibble[16];
	        
	        _fmemcpy(twibble, d->opgpkey + 1, 16);
            memset(iv, 0, sizeof(iv));
            initcfb_idea(iv, twibble, FALSE);

            /* If we're IDEA encrypting we must round the size of
               the data to be sent to be a multiple of 8 so that
               the entire IDEA frame is sent. */

            slen = (slen + 7) & (~7); 
            ideacfb(ebuf.buffer.buffer_val, (int) slen);
            close_idea();
            ebuf.compression |= fEncPGP;
        }

        /* One-time pad encryption. */

        if ((protocolSent == PROTOCOL_SPEAKFREE) && d->otpFileName[0]) {
            for (i = 0; i < slen; i++) {
                ebuf.buffer.buffer_val[i] ^= d->otp[i];
            }
            ebuf.compression |= fEncOTP;
        }
        pkl = slen + (sizeof(struct soundbuf) - BUFL);
    }
#endif
     
    {
    	int stat, nr;

		if (protocolSent == PROTOCOL_SPEAKFREE) {    	
			pkl = lpc10stuff(osb, pkl);
	        revlong(&osb->compression);
	        revlong(&osb->buffer.buffer_len);
	    }
		for (nr = 0; nr < ((lpc10compress && (robust > 1)) ? robust : 1); nr++) {
			stat = writeOutput(d, (LPSTR) osb, (int) pkl);
			if (stat < 0) {
				break;
			}
		}
        if (protocolSent == PROTOCOL_SPEAKFREE) {
	        revlong(&osb->compression);
	        revlong(&osb->buffer.buffer_len);
			lpc10unstuff(osb);
	    }
        if (stat < 0
&& WSAGetLastError() != WSAEINPROGRESS        ) {
            d->state = d->wantsInput ? SendingLiveAudio : Idle;
            d->wantsInput = FALSE;
            if (d->hFile != HFILE_ERROR) {
            	KillTimer(hwnd, 2);
	            _lclose(d->hFile);
	            d->hFile = HFILE_ERROR;
	        }
            socketerrorbox(hwnd, d);
            return FALSE;
        }
    }
    return TRUE;
}

/*	CHANGEAUDIOSTATE  --  Change transmitting / receiving state.  */

static void changeAudioState(HWND hwnd, LPCLIENT_DATA pClientData)
{
	if (pClientData->face_shown) {
		LPSTR hname = ((pClientData->uname != NULL) && (pClientData->uname[0]) &&
					   ((pClientData->uname[0] & 0xFF) != 0xFF)) ?
						pClientData->uname :
						(pClientData->localLoopback ? rstring(IDS_T_LOOPBACK) : 
						 (pClientData->modemConnection ?
		    			  rstring(IDS_T_MODEM_CONNECTION) : pClientData->szHost));
    	if (pClientData->wantsInput) {
    		char s[MAX_HOST + 20];
    		
    		strcpy(s, "==> ");
    		_fstrcat(s, hname);
    		SetWindowText(hwnd, s); 
    	} else {
    		SetWindowText(hwnd, hname);
    	} 
	} else {
		InvalidateRect(hwnd, NULL, FALSE);
		UpdateWindow(hwnd);
	}
}

/*  SHIPSOUNDBUFFER  --  Output sound buffer to connection.  */

void shipSoundBuffer(HWND hwnd, LPCLIENT_DATA pClientData)
{
	if (sqpacket != squelched) {
		RECT wr;
		POINT cp;
	
		squelched = sqpacket;
		GetWindowRect(hwnd, &wr);
		GetCursorPos(&cp);
		if (PtInRect(&wr, cp)) {
	    	SetCursor((pClientData->wantsInput || broadcasting || bConferencing) ? 
	    				(squelched ? boltCursor : earCursor) :
	    				phoneCursor);
			UpdateWindow(hwnd);			// Change cursor to indicate squelch state
		}
	}

	if (squelched) {
		return;
	}
    
    if (protocolSent == PROTOCOL_SPEAKFREE) {
	    sb.compression = fProtocol | (pClientData->ring ? (fSetDest | fDestSpkr) : 0);
	    pClientData->ring = FALSE;
	    sb.compression |= pClientData->debugging ? fDebug : 0;
	    sb.compression |= pClientData->loopback ? fLoopBack : 0;
	    sb.compression |= compression ? fComp2X : 0;
	    sb.compression |= gsmcompress ? fCompGSM : 0;
	    sb.compression |= adpcmcompress ? fCompADPCM : 0;
	    sb.compression |= lpccompress ? fCompLPC : 0;
	    sb.compression |= lpc10compress ? fCompLPC10 : 0;
	    /* Never offer face data to a multicast address.  It might be
	       nice, but the possibility of screw-ups is just too great
	       given the flakiness of multicast implementations. */
	    sb.compression |= ((faceFile != HFILE_ERROR) &&
	    	(!IN_MULTICAST(pClientData->inetSock.sin_addr.s_addr))) ? fFaceOffer : 0;
	    strcpy(sb.sendinghost, ourSendingHost);
	}
    sendpkt(hwnd, pClientData, &sb);
}

/*	SENDSESSIONCTRL  --  Send an RTP or VAT session control packet
						 on the control channel.  */
						 
static void sendSessionCtrl(LPCLIENT_DATA pClientData, char *msg, int msgl) 
{
	char *aux = (char *) &ebuf;
	int stat;

#ifdef CRYPTO			    			
	if ((!(protocolSent == PROTOCOL_SPEAKFREE)) && pClientData->rtpdeskey[0] &&
			!((protocolSent == PROTOCOL_RTP) && waProtNoRTCPCrypt)) {
		int vlen;
		des_key_schedule sched;
		des_cblock ivec;
						
		_fmemset(ivec, 0, 8);
						
		if (protocolSent == PROTOCOL_RTP) {
						
			/* Encrypted RTCP messages are prefixed with 4 random
			   bytes to prevent known plaintext attacks. */
						
			_fmemcpy(aux, &rtpdesrand, 4);
			_fmemcpy(aux + 4, msg, msgl);
			msgl += 4;
		} else {
			_fmemcpy(aux, msg, msgl);
		}
						
        /* If we're DES encrypting we must round the size of
		   the data to be sent to be a multiple of 8 so that
		   the entire DES frame is sent.  This applies only to
		   VAT, as the code that creates RTCP packets guarantees
           they're already padded to a multiple of 8 bytes. */
						
		vlen = msgl;
		msgl = (msgl + 7) & (~7);
		if (msgl > vlen) {
			_fmemset(aux + vlen, 0, msgl - vlen);
		}
		des_set_key((des_cblock FAR *) (((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 FAR *) 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 FAR *) 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 FAR *) 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 FAR *) 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 {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -