www.pudn.com > VOIP_server_client.rar > peer1_sock.cpp
#include "peer1_sock.h" #include#include "peer1_main.h" #include "peer1_resource.h" #include "peer1_sound_cap.h" #include "peer1_sound_play.h" // Constants =================================================================== #define BUF_SIZE 256 // Total packet length #define DATA_LEN 252 // Sound data length, 256-252=4 is header length #define F_BUF_SIZE 6250 #define MAJOR_VERSION_REQUIRED 1 #define MINOR_VERSION_REQUIRED 1 // Global Variables =========================================================== int achOutBuf[BUF_SIZE]; /* output buffer */ int achInBuf[BUF_SIZE]; /*input buffer */ int *achInBufP=achInBuf; // Input buffer pointer int *achOutBufP=achOutBuf; // Output buffer pointer char InBuffChar[1024]; // Input medium char buffer char OutBuffChar[1024]; // Output medium char buffer int outTextBuf[BUF_SIZE]; // input and output buffers for Text socket int inTextBuf[BUF_SIZE]; int *outTextBufP=outTextBuf; int *inTextBufP=inTextBuf; char outTextBufChar[1024]; char inTextBufChar[1024]; // int right_rcvSeq = 0; int mostRecentSound[DATA_LEN]; // Most recent sound data used when package loss float clk_sd; float clk_rc; float du; int sd_clk_times; struct sdRTP { int sdTS; int sdTS_ms; int sdSeq; int sdLen; }sdRtp; struct sdRTP *sdRtpP=&sdRtp; // Send packet header structure int old_sdSeq; struct rcvRTP { int rcvTS; int rcvTS_ms; int rcvSeq; int rcvLen; } rcvRtp; // Receive header structure struct sdTextHEADER { int Ctrl_Flag; int Ask_Con; int Aws_Con; int Ask_Discon; int Aws_Discon; } sdTextHeader; struct sdTextHEADER *sdTextHeaderP = &sdTextHeader; // Text send header struct rcvTextHEADER { int Ctrl_Flag; int Ask_Con; int Aws_Con; int Ask_Discon; int Aws_Discon; } rcvTextHeader; // Text receive header int nReturnCode; WSADATA wsaData; int nRet; SOCKET s_snd; //For sending int nRet1; SOCKET s_rcv; //For receiving; int nRet2; SOCKET s_text; // For text int totalLen; // receive total length int f_buf[F_BUF_SIZE]; // buffer between input buffer and play_buffer int *f_bufP=f_buf; int rcv_file_num=0; // Counter for marker share array and play buffer char st02[100]; float num_of_trans; float late_arrive_skip, num_of_rcv, num_of_mRecent, too_long_skip; int TS_old; int TS_delay; int first_rcv; // External Global Variables =================================================== extern BOOL thread1_stop,thread2_stop,thread3_stop,thread4_stop; struct play_buffer{ char play_data[PLAY_LENGTH]; }; extern struct play_buffer my_play_buffer[PLAY_BUF_LEN]; extern int share_array_rcv[PLAY_BUF_LEN]; extern float TS_cap; // Temp Variables ============================================================== //------------------------------------------------------- //*************** pr1() ********************************* //------------------------------------------------------- void pr1(HWND hwndDlg, char *st) { Display(st); } //-------------------------------------------------------------- //**************** WSA STARTUP ******************************* //--------------------------------------------------------------- int wsa_start(HWND hwndDlg, int err_restart) { first_rcv = 0; TS_old = 0; sdRtp.sdSeq=0; sd_clk_times = 0; rcv_file_num=0; right_rcvSeq = 0; TS_delay = delay_limit; if (err_restart == 0) { late_arrive_skip = 0; too_long_skip = 0; num_of_trans = 0; num_of_rcv = 0; num_of_mRecent = 0; } // Prepare version for WSAStartup() WORD wVersionRequired = MAKEWORD(MAJOR_VERSION_REQUIRED, MINOR_VERSION_REQUIRED); // Initialize the WinSock DLL nReturnCode = WSAStartup(wVersionRequired, &wsaData); if (nReturnCode != 0 ) { MessageBox(NULL,"Error on WSAStartup()", "Startup Error", MB_OK); return (0); } // Confirm that the version requested is available. if (wsaData.wVersion != wVersionRequired) { // Version needed is not available. MessageBox(NULL,"Wrong WinSock Version", "Version Error", MB_OK); WSACleanup(); return (0); } else { //pr1(hwndDlg, "WSA_startup OK!\r\n"); return (1); } } // ----------------------------------------------------------------------------- //******** Creating sending socket ********************************************* //------------------------------------------------------------------------------ void Connect_snd( HWND hwndDlg, WPARAM wParam, LPARAM lParam, char *ip) { SOCKADDR_IN stRmtAddr; /* ------opening a UDP soctet using socket() function*/ if (s_snd != INVALID_SOCKET) { nRet=closesocket(s_snd); s_snd=INVALID_SOCKET; } else { MessageBox(hwndDlg, "Invalid send Socket.", "Opening error-1", MB_OK); } s_snd=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (s_snd != INVALID_SOCKET) { //pr1(hwndDlg,"---send socket opening ok!\r\n"); } else { MessageBox(hwndDlg, "Send socket opening error.", "Opening error-2", MB_OK); } /* --------request notification for connect,read, write, and close events. and automatically make socket nonblocking)*/ nRet=WSAAsyncSelect(s_snd, hwndDlg, SM_ASYNC, FD_READ | FD_WRITE); if (nRet != SOCKET_ERROR){ //pr1(hwndDlg,"send socket async ok!\r\n"); } else { MessageBox(hwndDlg, "Send Socket Async Error.", "Opening error-3", MB_OK); } /* ----Remote IP and Port number for s_snd */ stRmtAddr.sin_family = AF_INET; stRmtAddr.sin_port = htons(1794); stRmtAddr.sin_addr.s_addr = inet_addr(ip); /* ----------connect--------- */ nRet=connect(s_snd, (LPSOCKADDR)&stRmtAddr, sizeof (struct sockaddr)); if (nRet != SOCKET_ERROR) { //pr1(hwndDlg,"connected to the destination ok!\r\n"); } else { MessageBox(hwndDlg, "Connection failed.", "connection error", MB_OK); } } //------------------------------------------------------------------------------ //************* Creating Receiving Socket ************************************** //------------------------------------------------------------------------------ void Connect_rcv( HWND hwndDlg, WPARAM wParam, LPARAM lParam) { SOCKADDR_IN stLclAddr; /* ------opening a UDP soctet using socket() function*/ if (s_rcv != INVALID_SOCKET) { nRet1=closesocket(s_rcv); s_rcv=INVALID_SOCKET; } else { MessageBox(hwndDlg, "Invalid Receive Socket.", "Opening error-1", MB_OK); } s_rcv=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (s_rcv != INVALID_SOCKET) { //pr1(hwndDlg,"---Receive socket opening ok!\r\n"); } else { MessageBox(hwndDlg, "Receive socket openning error.", "Opening error-2", MB_OK); } /* --------request notification for connect,read, write, and close events. and automatically make socket nonblocking)*/ nRet1=WSAAsyncSelect(s_rcv, hwndDlg, SM_ASYNC, FD_READ | FD_WRITE); if (nRet1 != SOCKET_ERROR) { //pr1(hwndDlg,"Receive Socket Async ok!\r\n"); } else { MessageBox(hwndDlg, "Receive Socket Async Error.", "Opening error-3", MB_OK); } /* ----Local IP and port number for s_rcv*/ stLclAddr.sin_family = PF_INET; stLclAddr.sin_port = htons(1794); stLclAddr.sin_addr.s_addr = inet_addr(LOC_ADDRESS); nRet1 = bind(s_rcv,(LPSOCKADDR)&stLclAddr, sizeof(struct sockaddr)); if (nRet1 == SOCKET_ERROR) { pr1(hwndDlg,"Receive socket bind failed!\r\n"); } } //------------------------------------------------------------------------------ // ******************** Creating Text Socket *********************************** //------------------------------------------------------------------------------ void Connect_text( HWND hwndDlg, WPARAM wParam, LPARAM lParam, char *ip) { SOCKADDR_IN stLclAddr; SOCKADDR_IN stRmtAddr; /* ------opening a UDP soctet using socket() function*/ if (s_text != INVALID_SOCKET) { nRet2=closesocket(s_text); s_text=INVALID_SOCKET; } s_text=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (s_text != INVALID_SOCKET) { //Display("---text socket opening ok!\r\n"); } else { MessageBox(hwndDlg, "Text Socket openning error.", "POP Info", MB_OK); } /* --------request notification for connect,read, write, and close events. and automatically make socket nonblocking)*/ nRet2=WSAAsyncSelect(s_text, hwndDlg, SM_ASYNC_TEXT, FD_READ | FD_WRITE); if (nRet2 != SOCKET_ERROR){ //Display("Text socket async ok!\r\n\r\n"); } else { MessageBox(hwndDlg, "Text Socket async error.", "POP Info", MB_OK); } /* ----name the socket, to receive requests as a server*/ stLclAddr.sin_family = AF_INET; stLclAddr.sin_port = htons(1790); stLclAddr.sin_addr.s_addr = inet_addr(LOC_ADDRESS); nRet2 = bind(s_text,(LPSOCKADDR)&stLclAddr, sizeof(struct sockaddr)); if (nRet != SOCKET_ERROR) { //Display("Text socket bind ok!\r\n"); } else { MessageBox(hwndDlg, "Text Socket naming error.", "POP Info", MB_OK); } /* ----name the socket, to receive requests as a client */ stRmtAddr.sin_family = AF_INET; stRmtAddr.sin_port = htons(1792); stRmtAddr.sin_addr.s_addr = inet_addr(ip); //Display("Naming the destination... \r\n\r\n"); /* ----------connect--------- */ nRet2=connect(s_text, (LPSOCKADDR)&stRmtAddr, sizeof (struct sockaddr)); if (nRet2 != SOCKET_ERROR) { //Display("Text connected to the destination ok!\r\n\r\n"); } else { MessageBox(hwndDlg, "Text Connection failed.", "POP Info", MB_OK); } } //------------------------------------------------------------------------------ //*********************** Sending Control(Through text sockrt) ***************** //------------------------------------------------------------------------------ void Send_Control(HWND hwndDlg, int ask_con, int aws_con, int ask_discon,int aws_discon) { // Copy send text headre into the text output buffer sdTextHeader.Ctrl_Flag = 1; sdTextHeader.Ask_Con = ask_con; sdTextHeader.Aws_Con = aws_con; sdTextHeader.Ask_Discon = ask_discon; sdTextHeader.Aws_Discon = aws_discon; memset(outTextBuf, 0, sizeof(outTextBuf)); memcpy(outTextBufP, sdTextHeaderP,sizeof(struct sdTextHEADER)); // sending memset(outTextBufChar, 0, sizeof(outTextBufChar)); memcpy(outTextBufChar,outTextBuf,sizeof(outTextBuf)); nRet = send(s_text, outTextBufChar, 1024, 0); } //------------------------------------------------------------------------------ //*********************** Sending Clk (Through text sockrt) (not used) ********* //------------------------------------------------------------------------------ void Send_Clk(HWND hwndDlg,int ctrl_flag, int ask_con, int aws_con, int ask_discon,int aws_discon) { // Copy send text headre into the text output buffer sdTextHeader.Ctrl_Flag = ctrl_flag; sdTextHeader.Ask_Con = ask_con; sdTextHeader.Aws_Con = aws_con; sdTextHeader.Ask_Discon = ask_discon; sdTextHeader.Aws_Discon = aws_discon; memset(outTextBuf, 0, sizeof(outTextBuf)); memcpy(outTextBufP, sdTextHeaderP,sizeof(struct sdTextHEADER)); // sending memset(outTextBufChar, 0, sizeof(outTextBufChar)); memcpy(outTextBufChar,outTextBuf,sizeof(outTextBuf)); clk_sd = clock(); nRet = send(s_text, outTextBufChar, 1024, 0); } //-------------------------------------------------------- //************** Sending message ************************* //-------------------------------------------------------- void Send_Msg(HWND hwndDlg,char *gszMsg) { //***copy send text header into the text output buffer sdTextHeader.Ctrl_Flag = 0; sdTextHeader.Ask_Con = 0; sdTextHeader.Aws_Con = 0; sdTextHeader.Ask_Discon = 0; sdTextHeader.Aws_Discon = 0; memset(outTextBuf, 0, sizeof(outTextBuf)); memcpy(outTextBufP,sdTextHeaderP,sizeof(struct sdTextHEADER)); //***copy text message into the output buffer outTextBufP=outTextBufP+5; memcpy(outTextBufP,gszMsg,strlen(gszMsg)); outTextBufP=outTextBufP-5; memset(outTextBufChar, 0, sizeof(outTextBufChar)); memcpy(outTextBufChar,outTextBuf,sizeof(outTextBuf)); nRet = send(s_text, outTextBufChar, 1024, 0); } //---------------------------------------------------------------------------- //******************** sending files ***************************************** //---------------------------------------------------------------------------- int send_file(HWND hwndDlg, char *Sound_Data) { achOutBufP=achOutBufP+4; memcpy(achOutBufP,Sound_Data,CAP_LENGTH); //put part of file into out buf achOutBufP=achOutBufP-4; sdRtp.sdTS = TS_cap; sdRtp.sdLen = CAP_LENGTH; memcpy(achOutBufP,sdRtpP,sizeof(struct sdRTP));//***copy RTP header ////////////////////////////// //*** Debugging-6 Simulate Out-of-sequence // Uncomment the following lines to simulate Out-of-sequence problems /*int old_sdSeq; if (sdRtp.sdSeq%100==3) { old_sdSeq = sdRtp.sdSeq; sdRtp.sdSeq = sdRtp.sdSeq+2; // Simulate packate loss memcpy(achOutBufP,sdRtpP,sizeof(struct sdRTP));//***copy RTP header sdRtp.sdSeq = old_sdSeq; } if (sdRtp.sdSeq%100==4) { old_sdSeq = sdRtp.sdSeq; sdRtp.sdSeq = sdRtp.sdSeq-1; // Simulate packate loss memcpy(achOutBufP,sdRtpP,sizeof(struct sdRTP));//***copy RTP header sdRtp.sdSeq = old_sdSeq; } if (sdRtp.sdSeq%100==5) { old_sdSeq = sdRtp.sdSeq; sdRtp.sdSeq = sdRtp.sdSeq-1; // Simulate packate loss memcpy(achOutBufP,sdRtpP,sizeof(struct sdRTP));//***copy RTP header sdRtp.sdSeq = old_sdSeq; } */ //sprintf(st02, "Seq = %d ", sdRtp.sdSeq); //Display(st02); /////////////////////////////// sdRtp.sdSeq = (sdRtp.sdSeq + 1) % 65536; memset(OutBuffChar, 0, sizeof(OutBuffChar)); memcpy(OutBuffChar,achOutBuf,sizeof(achOutBuf)); nRet = send(s_snd, OutBuffChar, 1024, 0); num_of_trans++; return (1); } //-------------------------------------------------------- //************* Handling Async Message ******************* //-------------------------------------------------------- void HandleAsyncMsg( HWND hwndDlg, WPARAM wParam, LPARAM lParam) { switch(WSAGETSELECTEVENT(lParam)) { case FD_CONNECT: //pr1(hwndDlg,"FD_CONNECT notification received\r\n"); break; case FD_WRITE: //Display("FD_WRITE notification received\r\n"); break; case FD_READ: if(thread1_stop==TRUE || thread2_stop==TRUE || thread3_stop==TRUE || thread4_stop==TRUE) break; else { rec_file(hwndDlg); break; } case FD_CLOSE: pr1(hwndDlg,"FD_CLOSE notification received\r\n"); break; } } //------------------------------------------------------------------------------ //************* Handling Async Message For Text ******************************** //------------------------------------------------------------------------------ void HandleAsyncMsg_Text( HWND hwndDlg, WPARAM wParam, LPARAM lParam) { switch(WSAGETSELECTEVENT(lParam)) { case FD_CONNECT: //pr1(hwndDlg,"Text FD_CONNECT notification received\r\n"); break; case FD_WRITE: //Display("Text FD_WRITE notification received\r\n"); break; case FD_READ: //Display("Text FD_READ notification received\r\n"); rec_text(hwndDlg); break; case FD_CLOSE: pr1(hwndDlg,"Text FD_CLOSE notification received\r\n"); break; } } //-------------------------------------------------------- //****************Close all socket************************ //-------------------------------------------------------- void Close_all_socket() { CloseSocket(s_rcv); CloseSocket(s_snd); } //-------------------------------------------------------- //**************** Closing Socket ************************ //-------------------------------------------------------- void CloseSocket(SOCKET sock) { int nRet; char szBuf[255]; shutdown(sock, 1); while(1) { nRet = recv( sock, szBuf, sizeof(szBuf), 0); if (nRet == 0 || nRet == SOCKET_ERROR) break; } shutdown(sock, 2); closesocket(sock); } //------------------------------------------------------------------------------ //******************** receive_text and Control messages *********************** //------------------------------------------------------------------------------ void rec_text(HWND hwndDlg) { memset(inTextBufChar, 0, sizeof(inTextBufChar)); nRet2=recv (s_text, inTextBufChar, sizeof(inTextBufChar), 0); memset(inTextBuf, 0, sizeof(inTextBuf)); memcpy(inTextBuf,inTextBufChar,sizeof(inTextBufChar)); rcvTextHeader.Ctrl_Flag = inTextBuf[0]; rcvTextHeader.Ask_Con = inTextBuf[1]; rcvTextHeader.Aws_Con = inTextBuf[2]; rcvTextHeader.Ask_Discon = inTextBuf[3]; rcvTextHeader.Aws_Discon = inTextBuf[4]; /*char st10[150]; sprintf(st10,"Ask_Con = %d Aws_Con = %d Ask_Discon = %d Aws_Discon = %d\r\n", rcvTextHeader.Ask_Con,rcvTextHeader.Aws_Con, rcvTextHeader.Ask_Discon,rcvTextHeader.Aws_Discon); Display(st10);*/ //************** Display Text ******* if( rcvTextHeader.Ctrl_Flag == 0 && rcvTextHeader.Ask_Con==0 && rcvTextHeader.Aws_Con==0 && rcvTextHeader.Ask_Discon==0 && rcvTextHeader.Aws_Discon==0) { inTextBufP=inTextBufP+5; Display(inTextBufP); inTextBufP=inTextBufP-5; pr1(hwndDlg,"\r\n\r\n"); } //************** Received Answers ******** if( rcvTextHeader.Ctrl_Flag == 1 && // ***** Accept invitation (by remote) rcvTextHeader.Ask_Con==0 && rcvTextHeader.Aws_Con==1 && rcvTextHeader.Ask_Discon==0 && rcvTextHeader.Aws_Discon==0) { SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_L_START, (LPARAM) 0); pr1(hwndDlg,"The invitation has been accepted. Talk channel has been established.\r\n"); } if( rcvTextHeader.Ctrl_Flag == 1 && // ***** Accept invitation (by remote) due to error rcvTextHeader.Ask_Con==0 && rcvTextHeader.Aws_Con==2 && rcvTextHeader.Ask_Discon==0 && rcvTextHeader.Aws_Discon==0) { SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_L_ERR_START, (LPARAM) 0); } if( rcvTextHeader.Ctrl_Flag == 1 && // ***** not Accept invitation (by remote) rcvTextHeader.Ask_Con==0 && rcvTextHeader.Aws_Con==99 && rcvTextHeader.Ask_Discon==0 && rcvTextHeader.Aws_Discon==0) { pr1(hwndDlg,"The invitation has been refused\r\n"); SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_R_STOP, (LPARAM) 0); } if( rcvTextHeader.Ctrl_Flag == 1 && // ***** Disconnection (occurred at remote) rcvTextHeader.Ask_Con==0 && rcvTextHeader.Aws_Con==0 && rcvTextHeader.Ask_Discon==0 && rcvTextHeader.Aws_Discon==1) { pr1(hwndDlg,"The talk channel has been disconnected\r\n"); } if( rcvTextHeader.Ctrl_Flag == 1 && // ***** Disconnection (by error) rcvTextHeader.Ask_Con==0 && rcvTextHeader.Aws_Con==0 && rcvTextHeader.Ask_Discon==0 && rcvTextHeader.Aws_Discon==2) { SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_ERR_START, (LPARAM) 0); } //*************** Sending answer ****** if( rcvTextHeader.Ctrl_Flag == 1 && // **** Being invited rcvTextHeader.Ask_Con==1 && rcvTextHeader.Aws_Con==0 && rcvTextHeader.Ask_Discon==0 && rcvTextHeader.Aws_Discon==0) { char st25[100]; sprintf(st25, "You are being invited for a talk.\r\n"); int ans; ans=MessageBox(hwndDlg, st25, "Invitation", MB_YESNO); if (ans==IDNO) // **** Say no { // sending Aws_Con=99 to remote Display("Talk channel was not established\r\n"); Send_Control(hwndDlg, 0,99,0,0); } else { // **** Say yes Send_Control(hwndDlg, 0,1,0,0); // **** Sending Aws_Con=1 to remote SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_R_START, (LPARAM) 0); Display("Talk channel has been established\r\n"); } } if( rcvTextHeader.Ctrl_Flag == 1 && // **** Being invited (due to remote error) rcvTextHeader.Ask_Con==2 && rcvTextHeader.Aws_Con==0 && rcvTextHeader.Ask_Discon==0 && rcvTextHeader.Aws_Discon==0) { Send_Control(hwndDlg, 0,2,0,0); // **** Sending Aws_Con=2 to remote SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_R_ERR_START, (LPARAM) 0); } if( rcvTextHeader.Ctrl_Flag == 1 && // After disconnected by remote, ack rcvTextHeader.Ask_Con==0 && rcvTextHeader.Aws_Con==0 && rcvTextHeader.Ask_Discon==1 && rcvTextHeader.Aws_Discon==0) { SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_R_STOP, (LPARAM) 0); Display("Talk channel has been disconnected\r\n"); Send_Control(hwndDlg, 0,0,0,1); // ***** Aws_Discon=1 } if( rcvTextHeader.Ctrl_Flag == 1 && // After disconnected by remote(by error) ack rcvTextHeader.Ask_Con==0 && rcvTextHeader.Aws_Con==0 && rcvTextHeader.Ask_Discon==2 && rcvTextHeader.Aws_Discon==0) { SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_R_ERR_STOP, (LPARAM) 0); Display("Talk channel has been disconnected(due to a remote site error).\r\n"); Send_Control(hwndDlg, 0,0,0,2); // ***** Aws_Discon=2 } // **** receice send_clk if( rcvTextHeader.Ctrl_Flag == 99 && rcvTextHeader.Ask_Con==0 && rcvTextHeader.Aws_Con==0 && rcvTextHeader.Ask_Discon==0 && rcvTextHeader.Aws_Discon==0) { Send_Clk(hwndDlg,100,0,0,0,0); } // **** when receive path delay clk sent back by remote if( rcvTextHeader.Ctrl_Flag == 100 && // clk_rc rcvTextHeader.Ask_Con==0 && rcvTextHeader.Aws_Con==0 && rcvTextHeader.Ask_Discon==0 && rcvTextHeader.Aws_Discon==0) { if(sd_clk_times < 10) { clk_rc = clock(); du = clk_rc - clk_sd; char st10[50]; sprintf(st10, "clk_sd = %f, clk_rc = %f, du/2 = %f\r\n", clk_sd, clk_rc,du/2); Display(st10); Send_Clk(hwndDlg,99,0,0,0,0); sd_clk_times++; } } } //--------------------------------------------------------------------------- //*********************** receive_file ************************************** //--------------------------------------------------------------------------- int rec_file(HWND hwndDlg) { int sleep_time; memset(InBuffChar, 0, sizeof(InBuffChar)); nRet=recv (s_rcv, InBuffChar, sizeof(InBuffChar), 0); memset(achInBuf, 0, sizeof(achInBuf)); memcpy(achInBuf,InBuffChar,sizeof(InBuffChar)); rcvRtp.rcvTS = achInBuf[0]; rcvRtp.rcvSeq = achInBuf[2]; rcvRtp.rcvLen = achInBuf[3]; //////////////////// //*** Debugging-7 Print sequence numbers of packets received //sprintf(st02, "%d ", rcvRtp.rcvSeq); //pr1(hwndDlg, st02); /////////////////// //////////////// if(++first_rcv > 1) { TS_delay = rcvRtp.rcvTS - TS_old; } TS_old = rcvRtp.rcvTS; if( (++first_rcv > 1) && (TS_delay < delay_limit) ) { sleep_time = delay_limit-TS_delay; while ( sleep_time > 5) { Sleep(5); sleep_time = sleep_time-5; } Sleep(sleep_time); handle_seq(hwndDlg); } else{ if( (++first_rcv > 1) && (TS_delay > too_long_limit) ) { //*** Debugging-8 Print too_long_skips //pr1(hwndDlg, " "); num_of_rcv++; too_long_skip++; achInBufP=achInBufP+4; memcpy(f_bufP,achInBufP,rcvRtp.rcvLen); memcpy(mostRecentSound,achInBufP,rcvRtp.rcvLen); achInBufP=achInBufP-4; if(rcvRtp.rcvSeq == right_rcvSeq) right_rcvSeq = (right_rcvSeq+1)%65536; if(rcvRtp.rcvSeq > right_rcvSeq) { right_rcvSeq = rcvRtp.rcvSeq; right_rcvSeq = (right_rcvSeq+1)%65536; } } else { /////////////// Sequence No. ///////////////////// handle_seq(hwndDlg); /////////////////////////////////////////////////////////// }//(too_long_skip else) } //(short sleep else) return (1); } //------------------------------------------------------------------- //************** Handle sequence No. ******************************** //------------------------------------------------------------------- void handle_seq(HWND hwndDlg) { if(rcvRtp.rcvSeq < right_rcvSeq) { //*** Debugging-9 Print late_arrive_skips //pr1(hwndDlg, " "); late_arrive_skip++; num_of_rcv++; } if(rcvRtp.rcvSeq == right_rcvSeq) //*** IF rcvRtp.rcvSeq == right_rcvSeq { num_of_rcv++; achInBufP=achInBufP+4; memcpy(f_bufP,achInBufP,rcvRtp.rcvLen); memcpy(mostRecentSound,achInBufP,rcvRtp.rcvLen); achInBufP=achInBufP-4; right_rcvSeq = (right_rcvSeq+1)%65536; memset(my_play_buffer[rcv_file_num].play_data, 0, PLAY_LENGTH); memcpy(my_play_buffer[rcv_file_num].play_data, f_buf, PLAY_LENGTH); if (share_array_rcv[rcv_file_num]==1) { pr1(hwndDlg, "**** error: share_array_rcv[rcv_file_num]==1\r\n"); SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_ERR_STOP, (LPARAM) 0); } else { share_array_rcv[rcv_file_num]=1; rcv_file_num++; if(rcv_file_num==PLAY_BUF_LEN) rcv_file_num=0; // ** wrap the buffer } } if(rcvRtp.rcvSeq > right_rcvSeq) //*** IF rcvRtp.rcvSeq > right_rcvSeq { num_of_rcv++; memcpy(f_bufP,mostRecentSound,rcvRtp.rcvLen); for(int j=0; j< rcvRtp.rcvSeq-right_rcvSeq; j++) //--Use most recent data { num_of_mRecent++; //*** Debugging-10 Print "most recent data".(when any lost packet recovery occurs) //pr1(hwndDlg, " "); memset(my_play_buffer[rcv_file_num].play_data, 0, PLAY_LENGTH); memcpy(my_play_buffer[rcv_file_num].play_data, f_buf, PLAY_LENGTH); if (share_array_rcv[rcv_file_num]==1) { pr1(hwndDlg, "**** error: share_array_rcv[rcv_file_num]==1\r\n"); SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_ERR_STOP, (LPARAM) 0); } else { share_array_rcv[rcv_file_num]=1; rcv_file_num++; if(rcv_file_num==PLAY_BUF_LEN) rcv_file_num=0; } } //--End of using most recent data right_rcvSeq = rcvRtp.rcvSeq; right_rcvSeq = (right_rcvSeq+1)%65536; //update right_rcvSeq //*** Debugging-11 Print "current data".(when any lost packet recovery occurs) //pr1(hwndDlg, " "); achInBufP=achInBufP+4; //-- Fill the current(bigger Seq) data memcpy(f_bufP,achInBufP,rcvRtp.rcvLen); memcpy(mostRecentSound,achInBufP,rcvRtp.rcvLen); achInBufP=achInBufP-4; memset(my_play_buffer[rcv_file_num].play_data, 0, PLAY_LENGTH); memcpy(my_play_buffer[rcv_file_num].play_data, f_buf, PLAY_LENGTH); if (share_array_rcv[rcv_file_num]==1) { pr1(hwndDlg, "**** error: share_array_rcv[rcv_file_num]==1\r\n"); SendMessage(hwndDlg, WM_COMMAND, (WPARAM)IDC_ERR_STOP, (LPARAM) 0); } else { share_array_rcv[rcv_file_num]=1; rcv_file_num++; if(rcv_file_num==PLAY_BUF_LEN) rcv_file_num=0; } } }