📄 main.cxx
字号:
PTRACE(3, "MCU\tCreating new conference " << conference->GetID() << " with number " << userSpecifiedRoom);
response = H323Connection::AnswerCallNow;
return conference;
}
// determine if the endpoint supports conference lists
// ver 2 clients are supposed to handle conference lists, but we know NM does not
// and we know OpenH323 apps prior to 1.14 cannot handle lists either
BOOL canDoConferenceList = connection.GetSignallingVersion() >= 2;
PString appInfo = connection.GetRemoteApplication();
if (appInfo.Find("NetMeeting") != P_MAX_INDEX)
canDoConferenceList = FALSE;
else if (appInfo.Find("OpenH323") != P_MAX_INDEX) {
PINDEX pos = appInfo.Find("OpenH323 ");
if (pos != P_MAX_INDEX) {
PStringArray version = appInfo.Mid(pos+9).Tokenise('.');
if (!(version.GetSize() == 3 &&
version[0].AsUnsigned() >= 1 &&
version[1].AsUnsigned() >= 14 &&
version[2].AsUnsigned() >= 0))
canDoConferenceList = FALSE;
}
}
// if no conference, and no default room, then send the terminal a conference list if it can understand it
if (canDoConferenceList) {
H323SignalPDU facilityPDU;
H225_Facility_UUIE & pdu = *facilityPDU.BuildFacility(connection, FALSE);
pdu.RemoveOptionalField(H225_Facility_UUIE::e_callIdentifier);
pdu.RemoveOptionalField(H225_Facility_UUIE::e_multipleCalls);
pdu.RemoveOptionalField(H225_Facility_UUIE::e_maintainConnection);
pdu.m_reason = H225_FacilityReason::e_conferenceListChoice;
pdu.IncludeOptionalField(H225_Facility_UUIE::e_conferences);
H225_ArrayOf_ConferenceList & conferenceList = pdu.m_conferences;
conferenceList.SetSize(0);
{
PWaitAndSignal m(conferenceManager.GetConferenceListMutex());
ConferenceList & roomList = conferenceManager.GetConferenceList();
ConferenceList::const_iterator r;
PINDEX i = 0;
for (r = roomList.begin(); r != roomList.end(); ++r) {
Conference & conf = *(r->second);
if (conf.IsVisible()) {
conferenceList.SetSize(conferenceList.GetSize()+1);
H225_ConferenceList & conference = conferenceList[i++];
conference.IncludeOptionalField(H225_ConferenceList::e_conferenceID);
conference.m_conferenceID = conf.GetID();
conference.IncludeOptionalField(H225_ConferenceList::e_conferenceAlias);
H323SetAliasAddress(conf.GetName(), conference.m_conferenceAlias, -1);
}
}
}
PTRACE(3, "MCU\tSending conference list");
// if the PDU write fails, then close the call
if (!connection.WriteSignalPDU(facilityPDU))
response = H323Connection::AnswerCallDenied;
else
response = H323Connection::AnswerCallDeferred;
return NULL;
}
// if there is a room to create, then join this call to that conference
PString roomToCreate = OpenMCU::Current().GetDefaultRoomName();
if (!roomToCreate.IsEmpty()) {
Conference * conference = conferenceManager.MakeConference(roomToCreate, "");
PTRACE(3, "MCU\tCreating/joining call to default room " << roomToCreate);
response = H323Connection::AnswerCallNow;
return conference;
}
PTRACE(3, "MCU\tRefusing call because no room specified, and no default room");
response = H323Connection::AnswerCallDenied;
return NULL;
}
///////////////////////////////////////////////////////////////
OpenMCUH323Connection::OpenMCUH323Connection(MyH323EndPoint & _ep, unsigned callReference)
: H323Connection(_ep, callReference), ep(_ep), connected(FALSE)
{
incomingAudio = NULL;
outgoingAudio = NULL;
conference = NULL;
conferenceMember = NULL;
sendingAllowed = TRUE;
audioReceiveCodecName = audioTransmitCodecName = "none";
#ifndef NO_MCU_VIDEO
incomingVideo = NULL;
outgoingVideo = NULL;
videoReceiveCodecName = videoTransmitCodecName = "none";
#endif
connected = FALSE;
cout << "Opening connection" << endl;
}
OpenMCUH323Connection::~OpenMCUH323Connection()
{
cout << "Closing connection" << endl;
}
void OpenMCUH323Connection::CleanUpOnCallEnd()
{
if (conference != NULL && conferenceMember != NULL) {
LogCall();
conferenceMember->WaitForClose();
ConferenceMember * cmToDelete = conferenceMember;
conferenceMember = NULL;
if (conference->RemoveMember(cmToDelete))
ep.GetConferenceManager().RemoveConference(conference->GetID());
delete cmToDelete;
}
H323Connection::CleanUpOnCallEnd();
}
H323Connection::AnswerCallResponse OpenMCUH323Connection::OnAnswerCall(const PString & /*caller*/,
const H323SignalPDU & setupPDU,
H323SignalPDU & /*connectPDU*/)
{
H323Connection::AnswerCallResponse response;
conference = ep.ConferenceRequest(*this, setupPDU, response);
if (conference == NULL)
return response;
connected = TRUE;
conferenceMember = new H323Connection_ConferenceMember(this);
conference->AddMember(conferenceMember);
return AnswerCallNow;
}
BOOL OpenMCUH323Connection::OnSendSignalSetup( H323SignalPDU & callProceedingPDU)
{
// We are making a connection to a remote EP so add this connection to
// the list of rooms and members.
// We will add them to the default room as we have no method of
// specifying which room our connection should join.
connected = TRUE;
conference = NULL;
PTRACE(3, "Conference\tOutgoing connection");
return H323Connection::OnSendSignalSetup( callProceedingPDU );
}
BOOL OpenMCUH323Connection::OpenAudioChannel(BOOL isEncoding, unsigned /* bufferSize */, H323AudioCodec & codec)
{
PString codecName= codec.GetMediaFormat();
codec.SetSilenceDetectionMode( H323AudioCodec::NoSilenceDetection );
// if (!codec.IsDescendant(H323_GSM0610Codec::Class()) &&
// - need to add MS-GSM here along with any other codecs
// !codec.IsDescendant(H323_muLawCodec::Class())) {
// cerr << "Unknown codec \"" << codecName << endl;
// return FALSE;
// }
if ((incomingAudio == NULL) && sendingAllowed) {
incomingAudio = new IncomingAudio(ep, *this);
}
if (outgoingAudio == NULL) {
outgoingAudio = new OutgoingAudio(ep, *this);
PFilePath fn = OpenMCU::Current().GetConnectingWAVFile();
PTRACE(4, "MCU\tOpening outgoing audio with file " << fn);
playFile.Open(fn, PFile::ReadOnly);
}
if (isEncoding) {
audioTransmitCodecName = codecName;
codec.AttachChannel(outgoingAudio, TRUE);
} else if (sendingAllowed) {
audioReceiveCodecName = codecName;
codec.AttachChannel(incomingAudio, TRUE);
}
return TRUE;
}
#ifndef NO_MCU_VIDEO
BOOL OpenMCUH323Connection::OpenVideoChannel(BOOL isEncoding,
H323VideoCodec & codec)
{
PStringStream codecName;
codecName << codec;
PWaitAndSignal mutex(videoMutex);
if (isEncoding) {
if (outgoingVideo == NULL) {
outgoingVideo = new OutgoingVideo(ep, *this, ep.videoFramesPS, ep.videoLarge);
codec.AttachChannel(outgoingVideo,TRUE);
// outgoingVideo->SetFrameSize(352>>1,288>>1);
}
/*At last. Modularity. The video codec is told the parameters of video compresion/decompression.
The only thing the video codec knows about the ouside world is how to acquire/render data, which
is via the video channel, provided by the OutgoingVideo class.
The codec does provide a second interface, through which ethernet packets enter (or leave) */
videoTransmitCodecName = codecName;
codec.SetTxQualityLevel(ep.videoTxQuality);
codec.SetBackgroundFill(ep.videoFill);
if (ep.videoBitRate != 0)
codec.SetMaxBitRate(ep.videoBitRate);
} else {
if ((incomingVideo == NULL) && sendingAllowed)
incomingVideo = new IncomingVideo(ep, *this);
codec.AttachChannel(incomingVideo,TRUE);
videoReceiveCodecName = codecName;
}
return TRUE;
}
#endif
void OpenMCUH323Connection::OnUserInputString(const PString & str)
{
if (conferenceMember != NULL)
conferenceMember->SendUserInputIndication(str);
}
BOOL OpenMCUH323Connection::OnIncomingAudio(const void * buffer, PINDEX amount)
{
if (conferenceMember != NULL)
conferenceMember->WriteAudio(buffer, amount);
return TRUE;
}
BOOL OpenMCUH323Connection::OnOutgoingAudio(void * buffer, PINDEX amount)
{
if (playFile.IsOpen()) {
if (!playFile.Read(buffer, amount)) {
PTRACE(4, "MCU\tFinished playing file");
playFile.Close();
} else {
int len = playFile.GetLastReadCount();
if (len < amount) {
memset(((BYTE *)buffer)+len, 0, amount-len);
}
return TRUE;
}
}
if (conferenceMember != NULL)
conferenceMember->ReadAudio(buffer, amount);
return TRUE;
}
#ifndef NO_MCU_VIDEO
BOOL OpenMCUH323Connection::OnOutgoingVideo(void * buffer, PINDEX & amount)
{
peerList.OnOutgoingVideo(buffer, amount);
}
BOOL OpenMCUH323Connection::OnIncomingVideo(const void * buffer, PINDEX amount)
{
return conference->OnIncomingVideo(buffer, amount);
}
#endif
///////////////////////////////////////////////////////////////
void OpenMCUH323Connection::LogCall(const BOOL accepted)
{
H323TransportAddress address = GetControlChannel().GetRemoteAddress();
PIPSocket::Address ip;
WORD port;
PStringStream stringStream, timeStream;
address.GetIpAndPort(ip, port);
timeStream << GetConnectionStartTime().AsString("hh:mm:ss");
stringStream << ' ' << "caller-ip:" << ip << ':' << port << ' '
<< GetRemotePartyName()
<< " room:" << ((conference != NULL) ? conference->GetNumber() : PString());
if (accepted) {
PStringStream connectionDuration;
connectionDuration << setprecision(0) << setw(5) << (PTime() - GetConnectionStartTime());
OpenMCU::Current().LogMessage(timeStream + stringStream + " connection duration:" + connectionDuration);
}
else
OpenMCU::Current().LogMessage(timeStream + " Call denied:" + stringStream);
}
///////////////////////////////////////////////////////////////
OutgoingAudio::OutgoingAudio(H323EndPoint & _ep, OpenMCUH323Connection & _conn)
: ep(_ep), conn(_conn)
{
os_handle = 0;
}
void OutgoingAudio::CreateSilence(void * buffer, PINDEX amount)
{
memset(buffer, 0, amount);
lastReadCount = amount;
}
BOOL OutgoingAudio::Read(void * buffer, PINDEX amount)
{
PWaitAndSignal mutexR(audioChanMutex);
if (!IsOpen())
return FALSE;
if (!delay.Delay(amount / 16)) {
// do the read call here, by calling conn.OnOutgoingAudio():
BOOL doSilence = !conn.OnOutgoingAudio(buffer, amount);
if (doSilence)
CreateSilence(buffer, amount);
}
lastReadCount = amount;
return TRUE;
}
BOOL OutgoingAudio::Close()
{
if (!IsOpen())
return FALSE;
PWaitAndSignal mutexC(audioChanMutex);
os_handle = -1;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////
IncomingAudio::IncomingAudio(H323EndPoint & _ep, OpenMCUH323Connection & _conn)
: ep(_ep), conn(_conn)
{
os_handle = 0;
}
BOOL IncomingAudio::Write(const void * buffer, PINDEX amount)
{
PWaitAndSignal mutexW(audioChanMutex);
if (!IsOpen())
return FALSE;
if (!delay.Delay(amount / 16))
conn.OnIncomingAudio(buffer, amount);
return TRUE;
}
BOOL IncomingAudio::Close()
{
if (!IsOpen())
return FALSE;
PWaitAndSignal mutexA(audioChanMutex);
os_handle = -1;
return TRUE;
}
///////////////////////////////////////////////////////////////////////////
// End of File ///////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -