📄 phonecarddevice.cxx
字号:
voidPhoneCardDevice::processRTP (){ deviceMutex.lock(); if ( audioStack == 0 ) { vusleep( 10000 ); deviceMutex.unlock(); return ; } //if ( hookStateOffhook == false ) {vusleep(10000); return;} RtpSessionState sessionState = audioStack->getSessionState(); //only process receive if receive is enabled if ( sessionState == rtp_session_recvonly || sessionState == rtp_session_sendrecv ) { inRtpPkt = audioStack->receive(); if ( inRtpPkt ) { //cerr << "receiving" << endl; //vusleep(500); //if (ioctl(myFD,IXJCTL_HOOKSTATE)==0) return; if ( inRtpPkt->getPayloadUsage() != RESID_RTP_RATE ) cpLog( LOG_DEBUG, "RtpStack API size doesn't match RESID_RTP_RATE" ); write( myFD, inRtpPkt->getPayloadLoc(), RESID_RTP_RATE ); // need to delete since RTP stack doesn't do it any more delete inRtpPkt; inRtpPkt = NULL; } } if ( sessionState == rtp_session_sendonly || sessionState == rtp_session_sendrecv ) { int cc; //if (ioctl(myFD,IXJCTL_HOOKSTATE)==0) return; { if ( sendRingback ) cc = getRingbackTone( outBufferPkt, RESID_RTP_RATE ); else cc = read( myFD, outBufferPkt, RESID_RTP_RATE ); } if ( audioStack ) { audioStack->transmitRaw( outBufferPkt, cc ); } } if ( audioStack && sessionState != rtp_session_inactive ) { audioStack->processRTCP(); } deviceMutex.unlock();}intPhoneCardDevice::addToFdSet( fd_set* fd ){ if ( audioActive ) { RtpSessionState sessionState = audioStack->getSessionState(); if ( sessionState == rtp_session_recvonly || sessionState == rtp_session_sendrecv ) { FD_SET( ( audioStack->getRtpRecv() )->getSocketFD(), fd ); FD_SET( ( audioStack->getRtcpRecv() )->getSocketFD(), fd ); } } FD_SET( myFD, fd ); return 0;} // end PhoneCardDevice::addToFdSet()//***************************************************************************// PhoneCardDevice::getRtpPort()//// description: creates a new rtp session and reserves a rtp port//***************************************************************************intPhoneCardDevice::getRtpPort(){ //this is an arbitrarily defined number const int MAX_RTP_PORT = 2 << 16-1; const int MIN_RTP_PORT = 10000; int port = 0; int minPort = MIN_RTP_PORT; deviceMutex.lock(); // create a rtp session if there is no existing session alread // this Rtp session will be idle if ( audioStack == 0 ) { audioStack = new RtpSession(0); } while ( 1 ) { // resever a rtp port port = audioStack->reserveRtpPort(minPort, MAX_RTP_PORT); minPort = (port > minPort) ? port : minPort; // attempt to reserve a rtcp port on port number higher than // the rtp port if ( port != 0 && audioStack->reserveRtcpPort(port + 1, 0) != 0 ) { break; } // if not successful allocating rtcp port, increment the minimum rtp // port and try again. If minPort reaches MAX_RTP_PORT, return 0 // to indicate port allocation failed. minPort += 2; if ( minPort > MAX_RTP_PORT ) { port = 0; break; } } deviceMutex.unlock(); return port;}//***************************************************************************// PhoneCardDevice::releaseRtpPort()//// description: destroy the rtp session and release the rtp port//***************************************************************************voidPhoneCardDevice::releaseRtpPort(){ deviceMutex.lock(); // destroy the rtp session if one exists if ( audioStack != 0 ) { int port = audioStack->releaseRtpPort(); cpLog( LOG_DEBUG, "rtp port %d released", port ); port = audioStack->releaseRtcpPort(); cpLog( LOG_DEBUG, "rtcp port %d released", port ); delete audioStack; audioStack = 0; } deviceMutex.unlock();}//***************************************************************************//***************************************************************************//***************************************************************************// PhoneCardDevice::audioStart//// description: creates a new rtp session and also allocates memory for// incoming and outgoing rtp packet. ioctl calls to initialize// the quicknet card.//***************************************************************************intPhoneCardDevice::audioStart( const HardwareAudioRequest& request ){ deviceMutex.lock(); cerr << "%%% Establishing audio %%%\n"; cerr << "%%% Listening on port: " << request.localPort << "\n"; cerr << "%%% Sending to host: " << request.remoteHost << "\n"; cerr << "%%% Sending to port: " << request.remotePort << "\n"; cerr << "%%% RTP packet size: " << request.rtpPacketSize << " ms\n"; // TBD, once stable, change asserts to checks which return errorcodes // create new audioStack for this audio session // 0 is rtpPayloadPCUM // last paramter, -1, disables jitter buffer if ( audioStack == 0 ) { int remoteRtcpPort = (request.remotePort > 0) ? request.remotePort + 1 : 0; int localRtcpPort = (request.localPort > 0) ? request.localPort + 1 : 0; cerr << "%%% remote rtcp port : " << remoteRtcpPort << "\n"; cerr << "%%% local rtcp port : " << localRtcpPort << "\n\n"; const char* remoteHost = 0; if ( request.remotePort != 0 ) remoteHost = request.remoteHost; audioStack = new RtpSession( remoteHost, request.remotePort, request.localPort, remoteRtcpPort, localRtcpPort, rtpPayloadPCMU, rtpPayloadPCMU, 5 ); //if ( request.remotePort != 0 ) { ioctl( myFD, IXJCTL_REC_CODEC, ULAW ); ioctl( myFD, IXJCTL_REC_START ); //} //if ( request.localPort != 0 ) { ioctl( myFD, IXJCTL_PLAY_CODEC, ULAW ); ioctl( myFD, IXJCTL_PLAY_START ); //} ioctl( myFD, IXJCTL_AEC_START, 1 );#if 0 // Echo Cancellation doesn't work with VM. if (request.echoCancellation) { ioctl(myFD, IXJCTL_AEC_START, 1); cerr << "echoCancellation is on" << endl; } else { cpLog(LOG_DEBUG, "echoCancellation is off"); ioctl(myFD, IXJCTL_AEC_START, 0); } ioctl(myFD, IXJCTL_MIXER, 0x0C03); // 06 is too soft ioctl(myFD, IXJCTL_MIXER, 0x0F01); // 02 is too soft#endif } else { cerr << "%%%% we are turning half duplex into full duplex" << endl; //need to determine what mode RtpSession is in RtpSessionState sessionState = audioStack->getSessionState(); switch ( sessionState ) { case rtp_session_sendonly: //turn on the receive if ( request.localPort != 0 ) { cerr << "%%%%turning on receive" << endl; cerr << "%%%%local host " << request.localPort << endl; cerr << "%%%%local port " << request.localPort << endl; audioStack->setSessionState( rtp_session_sendrecv ); audioStack->setReceiver( request.localPort, request.localPort + 1, 0, rtpPayloadPCMU, rtpPayloadPCMU, 5); } //restart the quicknet card ioctl(myFD, IXJCTL_REC_STOP); ioctl(myFD, IXJCTL_PLAY_STOP); ioctl(myFD, IXJCTL_REC_CODEC, ULAW); ioctl(myFD, IXJCTL_REC_START); ioctl(myFD, IXJCTL_PLAY_CODEC, ULAW); ioctl(myFD, IXJCTL_PLAY_START); break; case rtp_session_recvonly: //turn on the send cerr << "%%%%turning on the send" << endl; cerr << "%%%%remote host " << request.remoteHost << endl; cerr << "%%%%remote port " << request.remotePort << endl; if ( request.remotePort != 0 ) { audioStack->setSessionState(rtp_session_sendrecv); audioStack->setTransmiter(request.remoteHost, request.remotePort, request.remotePort + 1, rtpPayloadPCMU, rtpPayloadPCMU); } //restart the quicknet card ioctl(myFD, IXJCTL_REC_STOP); ioctl(myFD, IXJCTL_PLAY_STOP); ioctl(myFD, IXJCTL_REC_CODEC, ULAW); ioctl(myFD, IXJCTL_REC_START); ioctl(myFD, IXJCTL_PLAY_CODEC, ULAW); ioctl(myFD, IXJCTL_PLAY_START); break; case rtp_session_sendrecv: return 0; break; default: audioStack->setSessionState( rtp_session_sendrecv ); //turn on the send if ( request.remotePort != 0 ) { audioStack->setTransmiter(request.remoteHost, request.remotePort, request.remotePort + 1, rtpPayloadPCMU, rtpPayloadPCMU); } //turn on the receive if ( request.localPort != 0 ) { audioStack->setReceiver(request.localPort, request.localPort + 1, 0, rtpPayloadPCMU, rtpPayloadPCMU, 5); } break; } } if ( request.sendRingback ) startSendRingback(); else stopSendRingback(); RtpSessionState sessionState = audioStack->getSessionState(); if ( sessionState == rtp_session_sendonly || sessionState == rtp_session_recvonly) { audioActive = false; audioHalfActive = true; } else if ( sessionState == rtp_session_sendrecv ) { audioActive = true; audioHalfActive = false; } else { audioActive = false; audioActive = true; } inRtpPkt = 0; audioStack->setApiFormat( rtpPayloadPCMU, RESID_RTP_RATE ); audioStack->setNetworkFormat( rtpPayloadPCMU, request.rtpPacketSize * 8 ); // hasPlayed = false;#if 0 // Echo Cancellation doesn't work with VM. if (request.echoCancellation) { ioctl(myFD, IXJCTL_AEC_START, 1); cerr << "echoCancellation is on" << endl; } else { cpLog(LOG_DEBUG, "echoCancellation is off"); ioctl(myFD, IXJCTL_AEC_START, 0); } ioctl(myFD, IXJCTL_MIXER, 0x0C03); // 06 is too soft ioctl(myFD, IXJCTL_MIXER, 0x0F01); // 02 is too soft#endif deviceMutex.unlock(); return 0;} // end PhoneCardDevice::audioStart()//***************************************************************************// PhoneCardDevice::audioStop//// description: tears down audio. cleans up by delete objects created when// audioStart was called... audioStack, rtp packets.//***************************************************************************intPhoneCardDevice::audioStop(){ cpLog( LOG_DEBUG, "*** Stopping audio ***" ); if ( !audioActive ) return 1; // mark audio as deactivated. audioActive = false; audioHalfActive = false; // hasPlayed = false; vusleep( 200 ); // make hardware calls to stop audio deviceMutex.lock(); ioctl( myFD, IXJCTL_REC_STOP ); ioctl( myFD, IXJCTL_PLAY_STOP ); ioctl( myFD, IXJCTL_AEC_STOP ); // TBD, need to close and reopen device to stablize ipjack // hardware, hopefully this can be cleaned up with new driver#if 0 close( myFD ); myFD = open( myDeviceName, O_RDWR ); if ( myFD < 0 ) { cpLog( LOG_ERR, "Cannot reopen %s", myDeviceName ); exit( 1 ); }#endif // close RTP session if ( audioStack ) { RtpSessionState sessionState = audioStack->getSessionState(); if ( sessionState == rtp_session_sendonly || sessionState == rtp_session_sendrecv ) { audioStack->transmitRTCPBYE(); } } if ( inRtpPkt ) { delete inRtpPkt; inRtpPkt = 0; } if ( audioStack ) { delete audioStack; audioStack = 0; } deviceMutex.unlock(); return 0;} // end PhoneCardDevice::audioStop()//***************************************************************************// PhoneCardDevice::audioSuspend//// description: suspend the RTP transmit and receive, and also stop the////***************************************************************************intPhoneCardDevice::audioSuspend (){ deviceMutex.lock(); cpLog( LOG_INFO, "Suspending audio" ); cpLog( LOG_INFO, "Setting all RTP/RTCP ports to 0" ); if ( audioStack != 0 ) { //set rtp session to inactive audioStack->setSessionState( rtp_session_inactive ); audioStack->setReceiver( 0, 0, 0, rtpPayloadPCMU, rtpPayloadPCMU, 5 ); audioStack->setTransmiter( 0, 0, 0, rtpPayloadPCMU, rtpPayloadPCMU ); } ioctl( myFD, IXJCTL_REC_STOP ); ioctl( myFD, IXJCTL_PLAY_STOP ); ioctl( myFD, IXJCTL_AEC_STOP ); deviceMutex.unlock(); return 0;} // end PhoneCardDevice::audioSuspend()//***************************************************************************// PhoneCardDevice::audioResume//// description: resume the rtp session using the new sdp information// enable the quicknet card audio//***************************************************************************intPhoneCardDevice::audioResume( const HardwareAudioRequest& request ){ deviceMutex.lock(); if ( audioStack == 0 ) { cpLog( LOG_ERR, "Try to resume an existing audio channel" ); cpLog( LOG_ERR, "No existing audio channel" ); deviceMutex.unlock(); return 0; } cpLog( LOG_INFO, "Resuming audio" ); cpLog( LOG_INFO, "Listening on port: %d", request.localPort ); cpLog( LOG_INFO, "Sending to host: %s", request.remoteHost ); cpLog( LOG_INFO, "Sending to port: %d", request.remotePort ); cpLog( LOG_INFO, "RTP packet size: %d", request.rtpPacketSize ); //resuming audio channel //int remoteRtcpPort = (request.remotePort > 0) ? request.remotePort + 1 : 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -