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

📄 main.cxx

📁 openmcu 是开源的H.323会议服务器,需要pwlib 和 openh323的编译库文件支持。
💻 CXX
📖 第 1 页 / 共 3 页
字号:
    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 + -