📄 quicknetdevice.cxx
字号:
{ 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); FD_SET( stdinFD, fd ); return 0;} // end QuickNetDevice::addToFdSet()//***************************************************************************// QuickNetDevice::getRtpPort()//// description: creates a new rtp session and reserves a rtp port//***************************************************************************intQuickNetDevice::getRtpPort(){ //this is an arbitrarily defined number const int HIGH_RTP_PORT = UaConfiguration::instance()->getMaxRtpPort(); const int LOW_RTP_PORT = UaConfiguration::instance()->getMinRtpPort(); int port = 0; int lowPort = LOW_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(lowPort, HIGH_RTP_PORT); lowPort = (port > lowPort) ? port : lowPort; // attempt to reserve a rtcp port on port number higher than // the rtp port if ( port != 0 && audioStack->reserveRtcpPort(port + 1, 0) != 0 ) { cpLog( LOG_DEBUG, "Reserved rtp/rtcp ports %d/%d", port, port+1 ); break; } // if not successful allocating rtcp port, increment the minimum rtp // port and try again. If lowPort reaches HIGH_RTP_PORT, return 0 // to indicate port allocation failed. lowPort += 2; if ( lowPort > HIGH_RTP_PORT ) { port = 0; break; } } deviceMutex.unlock(); return port;}//***************************************************************************// QuickNetDevice::releaseRtpPort()//// description: destroy the rtp session and release the rtp port//***************************************************************************voidQuickNetDevice::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();}//***************************************************************************// QuickNetDevice::audioStart//// description: creates a new rtp session and also allocates memory for// incoming and outgoing rtp packet. ioctl calls to initialize// the quicknet card.//***************************************************************************intQuickNetDevice::audioStart (const HardwareAudioRequest& request){ deviceMutex.lock(); cpLog( LOG_DEBUG, ">> Establishing audio" ); cpLog( LOG_DEBUG, ">> Listening on port: %d", request.localPort ); cpLog( LOG_DEBUG, ">> Sending to host : %s", request.remoteHost ); cpLog( LOG_DEBUG, ">> Sending to port : %d", request.remotePort ); cpLog( LOG_DEBUG, ">> RTP packet size : %d ms", request.rtpPacketSize ); if ( audioStack == 0 ) { int remoteRtcpPort = (request.remotePort > 0) ? request.remotePort + 1 : 0; int localRtcpPort = (request.localPort > 0) ? request.localPort + 1 : 0; cpLog( LOG_DEBUG, "Remote RTCP port : %d", remoteRtcpPort ); cpLog( LOG_DEBUG, "Local RTCP port : %d", localRtcpPort ); const char* remoteHost = 0; if ( request.remotePort != 0 ) remoteHost = request.remoteHost; audioStack = new RtpSession(remoteHost, request.remotePort, request.localPort, remoteRtcpPort, localRtcpPort, rtpPayloadPCMU, rtpPayloadPCMU, 5); ioctl(myFD, PHONE_REC_CODEC, ULAW); ioctl(myFD, PHONE_REC_START); ioctl(myFD, PHONE_PLAY_CODEC, ULAW); ioctl(myFD, PHONE_PLAY_START); ioctl(myFD, IXJCTL_AEC_START, 1); } else { cpLog( LOG_DEBUG, "Modifying existing audio connection" ); //need to determine what mode RtpSession is in RtpSessionState sessionState = audioStack->getSessionState(); switch ( sessionState ) { case rtp_session_sendonly: cpLog( LOG_DEBUG, "Session sendonly" ); //turn on the receive if ( request.localPort != 0 ) { cpLog( LOG_DEBUG, "turning on receive" ); cpLog( LOG_DEBUG, "local host: %d", request.localPort ); cpLog( LOG_DEBUG, "local port: %d", request.localPort ); audioStack->setSessionState(rtp_session_sendrecv); audioStack->setReceiver(request.localPort, request.localPort + 1, 0, rtpPayloadPCMU, rtpPayloadPCMU, 5); } //restart the quicknet card ioctl(myFD, PHONE_REC_STOP); ioctl(myFD, PHONE_PLAY_STOP); ioctl(myFD, PHONE_REC_CODEC, ULAW); ioctl(myFD, PHONE_REC_START); ioctl(myFD, PHONE_PLAY_CODEC, ULAW); ioctl(myFD, PHONE_PLAY_START); break; case rtp_session_recvonly: cpLog( LOG_DEBUG, "Session recvonly" ); //turn on the send cpLog( LOG_DEBUG, "turning on the send" ); cpLog( LOG_DEBUG, "remote host: %d", request.remoteHost ); cpLog( LOG_DEBUG, "remote port: %d", request.remotePort ); 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, PHONE_REC_STOP); ioctl(myFD, PHONE_PLAY_STOP); ioctl(myFD, PHONE_REC_CODEC, ULAW); ioctl(myFD, PHONE_REC_START); ioctl(myFD, PHONE_PLAY_CODEC, ULAW); ioctl(myFD, PHONE_PLAY_START); break; case rtp_session_sendrecv: cpLog( LOG_DEBUG, "Session sendrecv" ); return 0; break; default: ioctl(myFD, PHONE_PLAY_STOP); ioctl(myFD, PHONE_REC_STOP); if ( request.remotePort != 0 && request.localPort != 0 ) { audioStack->setSessionState( rtp_session_sendrecv ); cpLog( LOG_DEBUG, "Session state is sendrecv" ); } else if ( request.localPort != 0 ) { audioStack->setSessionState( rtp_session_recvonly ); cpLog( LOG_DEBUG, "Session state is recvonly" ); } else if ( request.remotePort != 0 ) { audioStack->setSessionState( rtp_session_sendonly ); cpLog( LOG_DEBUG, "Session state is sendonly" ); } else { cpLog( LOG_ERR, "Session state is undefined" ); } //turn on the receive if ( request.localPort != 0 ) { cpLog( LOG_DEBUG, "Turn on recv" ); audioStack->setReceiver( request.localPort, request.localPort + 1, 0, rtpPayloadPCMU, rtpPayloadPCMU, 5 ); ioctl(myFD, PHONE_PLAY_CODEC, ULAW); ioctl(myFD, PHONE_PLAY_START); } //turn on the send if ( request.remotePort != 0 ) { cpLog( LOG_DEBUG, "Turn on send" ); audioStack->setTransmiter( request.remoteHost, request.remotePort, request.remotePort + 1, rtpPayloadPCMU, rtpPayloadPCMU ); ioctl(myFD, PHONE_REC_CODEC, ULAW); ioctl(myFD, PHONE_REC_START); }#if 0 ioctl(myFD, PHONE_REC_STOP); ioctl(myFD, PHONE_PLAY_STOP); ioctl(myFD, PHONE_REC_CODEC, ULAW); ioctl(myFD, PHONE_REC_START); ioctl(myFD, PHONE_PLAY_CODEC, ULAW); ioctl(myFD, PHONE_PLAY_START);#endif 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 { audioActive = true; audioHalfActive = false; } // inRtpPkt = 0; if( inRtpPkt ) { delete inRtpPkt; inRtpPkt = 0; } audioStack->setApiFormat (rtpPayloadPCMU, RESID_RTP_RATE); audioStack->setNetworkFormat (rtpPayloadPCMU, request.rtpPacketSize * 8); deviceMutex.unlock(); return 0;} // end QuickNetDevice::audioStart()//***************************************************************************// QuickNetDevice::audioStop//// description: tears down audio. cleans up by delete objects created when// audioStart was called... audioStack, rtp packets.//***************************************************************************intQuickNetDevice::audioStop(){ cpLog( LOG_DEBUG, "*** Stopping audio ***" ); // mark audio as deactivated. audioActive = false; audioHalfActive = false; vusleep(200); // make hardware calls to stop audio deviceMutex.lock(); ioctl(myFD, PHONE_REC_STOP); ioctl(myFD, PHONE_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); ioctl(myFD, IXJCTL_PORT, PORT_POTS); 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 QuickNetDevice::audioStop()//***************************************************************************// QuickNetDevice::audioSuspend//// description: suspend the RTP transmit and receive, and also stop the////***************************************************************************intQuickNetDevice::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, PHONE_REC_STOP); ioctl(myFD, PHONE_PLAY_STOP); ioctl(myFD, IXJCTL_AEC_STOP); audioActive = false; audioHalfActive = false; deviceMutex.unlock(); return 0;} // end QuickNetDevice::audioSuspend()//***************************************************************************// QuickNetDevice::audioResume//// description: resume the rtp session using the new sdp information// enable the quicknet card audio//***************************************************************************intQuickNetDevice::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; //int localRtcpPort=(request.localPort>0)?request.localPort+1:0; const char* remoteHost = 0; if ( request.remotePort != 0 ) remoteHost = request.remoteHost; if ( request.localPort != 0 && request.remotePort != 0 ) { //full duplex audio audioStack->setSessionState(rtp_session_sendrecv); audioStack->setReceiver(request.localPort, request.localPort + 1, 0, rtpPayloadPCMU, rtpPayloadPCMU, 5); audioStack->setTransmiter(request.remoteHost, request.remotePort, request.remotePort + 1, rtpPayloadPCMU, rtpPayloadPCMU); ioctl(myFD, PHONE_PLAY_CODEC, ULAW); ioctl(myFD, PHONE_PLAY_START); ioctl(myFD, PHONE_REC_CODEC, ULAW); ioctl(myFD, PHONE_REC_START); audioActive = true; audioHalfActive = false; } else if ( request.localPort != 0 ) { //receive only audioStack->setSessionState(rtp_session_sendrecv); audioStack->setReceiver(request.localPort, request.localPort + 1, 0, rtpPayloadPCMU, rtpPayloadPCMU, 5); ioctl(myFD, PHONE_PLAY_CODEC, ULAW); ioctl(myFD, PHONE_PLAY_START); audioActive = false; audioHalfActive = true; } else if ( request.remotePort != 0 ) { //transmit only audioStack->setSessionState(rtp_session_sendrecv); audioStack->setTransmiter(request.remoteHost, request.remotePort, request.remotePort + 1, rtpPayloadPCMU, rtpPayloadPCMU); ioctl(myFD, PHONE_REC_CODEC, ULAW); ioctl(myFD, PHONE_REC_START); audioActive = false; audioHalfActive = true; }#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, PHONE_MIXER, 0x0C03); // 06 is too soft ioctl(myFD, PHONE_MIXER, 0x0F01); // 02 is too soft#endif if ( request.sendRingback ) startSendRingback(); else stopSendRingback(); deviceMutex.unlock(); return 0;} // end QuickNetDevice::audioResume()//***************************************************************************// QuickNetDevice::provideTone//// description: quicknet does not provide all the tone that are needed.// this function will provide the tone for quicknet by playing// a sound file of that particular tone.//***************************************************************************void
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -