OsStatus ConferenceEngineMediaInterface::playAudioForIndividual(int connectionId,
                                                                const char* url,
                                                                OsNotification* event)
{
    mLock.acquire();
    
    assert(url);
    
    int iRC;

    ConferenceEngineMediaConnection* pMediaConnection = getMediaConnection(connectionId) ;
    if (pMediaConnection)
    {
        // Set up a notification for play done event        
        pMediaConnection->mpPlayNotify = event;
        
        iRC = mpConferenceEngine->GIPSConf_StartPlayFileToChannel(connectionId, url);
        if (iRC != 0)
        {
            OsSysLog::add(FAC_MP, PRI_ERR,
                          "ConferenceEngineMediaInterface::playAudioForIndividual GIPSConf_StartPlayFileToChannel failed with error = %d.",
                          mpConferenceEngine->GIPSConf_GetLastError());
        }
        assert(iRC == 0);
    }

    mLock.release();
    return OS_SUCCESS;
}
OsStatus ConferenceEngineMediaInterface::getPrimaryCodec(int connectionId,
                                                         UtlString& codec,
                                                         UtlString& videoCodec,
                                                         int* payloadType,
                                                         int* videoPayloadType)
{
    mLock.acquire();
    OsStatus rc = OS_FAILED;

    ConferenceEngineMediaConnection* pMediaConnection = getMediaConnection(connectionId);
    if (pMediaConnection && pMediaConnection->mpPrimaryCodec)
    {
        if (getCodecNameByType(pMediaConnection->mpPrimaryCodec->getCodecType(), codec))
        {
            if (NULL != payloadType)
            {
                *payloadType = pMediaConnection->mRtpPayloadType;
            }
            rc = OS_SUCCESS;
        }
    }

    mLock.release();
    return rc;
}
OsStatus ConferenceEngineMediaInterface::stopRtpReceive(int connectionId)
{
    mLock.acquire();
    int iRC ;

    ConferenceEngineMediaConnection* pMediaConnection = getMediaConnection(connectionId) ;
    if (pMediaConnection && pMediaConnection->mRtpReceiving)
    {
        pMediaConnection->mRtpReceiving = FALSE ;

        iRC = mpConferenceEngine->GIPSConf_StopPlayoutToMeeting(connectionId) ;
        if (iRC != 0)
        {
            Os::Logger::instance().log(FAC_MP, PRI_ERR,
                          "ConferenceEngineMediaInterface::stopRtpReceive GIPSConf_StopPlayoutToMeeting failed with error = %d.",
                          mpConferenceEngine->GIPSConf_GetLastError());
        }
        assert(iRC == 0) ;

        iRC = mpConferenceEngine->GIPSConf_StopListenToParticipant(connectionId) ;
        if (iRC != 0)
        {
            Os::Logger::instance().log(FAC_MP, PRI_ERR,
                          "ConferenceEngineMediaInterface::stopRtpReceive GIPSConf_StopListenToParticipant failed with error = %d.",
                          mpConferenceEngine->GIPSConf_GetLastError());
        }
        assert(iRC == 0);
    }

    mLock.release();
    return OS_SUCCESS ;
}
OsStatus CpPhoneMediaInterface::addAlternateDestinations(int connectionId,
                                                         unsigned char cPriority,
                                                         const char* rtpHostAddress, 
                                                         int port,
                                                         bool bRtp)
{
    OsStatus returnCode = OS_NOT_FOUND;
    CpPhoneMediaConnection* mediaConnection = getMediaConnection(connectionId);
    if (mediaConnection)
    {
        if (bRtp)
        {
            if (mediaConnection->mpRtpSocket)
            {
                mediaConnection->mpRtpSocket->addAlternateDestination(
                        rtpHostAddress, port, 
                        cPriority) ;
                returnCode = OS_SUCCESS;
            }
        }
        else
        {
            if (mediaConnection->mpRtcpSocket)
            {
                mediaConnection->mpRtcpSocket->addAlternateDestination(
                        rtpHostAddress, port, 
                        cPriority) ;
                returnCode = OS_SUCCESS;
            }

        }
    }

    return returnCode ;
}
OsStatus ConferenceEngineMediaInterface::stopAudioForIndividual(int connectionId)
{
    mLock.acquire();

    int iRC;

    ConferenceEngineMediaConnection* pMediaConnection = getMediaConnection(connectionId) ;
    if (pMediaConnection)
    {
        // Set up a notification for play done event
        pMediaConnection->mpPlayNotify = NULL;

        iRC = mpConferenceEngine->GIPSConf_StopPlayFileToChannel(connectionId);
        if (iRC != 0)
        {
            Os::Logger::instance().log(FAC_MP, PRI_ERR,
                          "ConferenceEngineMediaInterface::stopAudioForIndividual GIPSConf_StopPlayFileToChannel failed with error = %d.",
                          mpConferenceEngine->GIPSConf_GetLastError());
        }
        assert(iRC == 0);
    }

    mLock.release();
    return OS_SUCCESS;
}
OsStatus CpPhoneMediaInterface::setConnectionDestination(int connectionId,
                                         const char* remoteRtpHostAddress,
                                         int remoteAudioRtpPort,
                                         int remoteAudioRtcpPort,
                                         int remoteVideoRtpPort,
                                         int remoteVideoRtcpPort)
{
   OsStatus returnCode = OS_NOT_FOUND;
   CpPhoneMediaConnection* mediaConnection = getMediaConnection(connectionId);


   if(mediaConnection &&
       remoteRtpHostAddress && *remoteRtpHostAddress)
   {
       mediaConnection->mDestinationSet = TRUE;
       mediaConnection->mRtpSendHostAddress.remove(0);
       mediaConnection->mRtpSendHostAddress.append(remoteRtpHostAddress);
       mediaConnection->mRtpSendHostPort = remoteAudioRtpPort;
       mediaConnection->mRtcpSendHostPort = remoteAudioRtcpPort;

       if(mediaConnection && mediaConnection->mpRtpSocket)
       {
          mediaConnection->mpRtpSocket->doConnect(remoteAudioRtpPort, remoteRtpHostAddress, TRUE);
          returnCode = OS_SUCCESS;
#ifdef TEST_PRINT
          OsSysLog::add(FAC_CP, PRI_DEBUG, "Setting RTP socket destination id: %d address: %s port:"
             " %d socket: %p descriptor: %d\n", 
             connectionId, remoteRtpHostAddress, remoteAudioRtpPort, 
             mediaConnection->mpRtpSocket, mediaConnection->mpRtpSocket->getSocketDescriptor());
          //assert( strcmp(remoteRtpHostAddress, "0.0.0.0"));
#endif
       }

       if(mediaConnection->mpRtcpSocket)
       {
          mediaConnection->mpRtcpSocket->doConnect(remoteAudioRtcpPort, remoteRtpHostAddress, TRUE);
#ifdef TEST_PRINT
          OsSysLog::add(FAC_CP, PRI_DEBUG, "Setting RTCP socket destination id: %d address: %s port:"
             " %d socket: %p descriptor: %d\n", 
             connectionId, remoteRtpHostAddress, remoteAudioRtpPort, 
             mediaConnection->mpRtcpSocket, mediaConnection->mpRtcpSocket->getSocketDescriptor());
          //assert( strcmp(remoteRtpHostAddress, "0.0.0.0"));
#endif
       }
       else
       {
           OsSysLog::add(FAC_CP, PRI_ERR, "ERROR: no rtp socket in setConnectionDestination\n");
       }
   }
   else
   {
       OsSysLog::add(FAC_CP, PRI_ERR, "CpPhoneMediaInterface::setConnectionDestination with"
                   " zero length host address\n");
   }

   return(returnCode);
}
OsStatus CpPhoneMediaInterface::deleteConnection(int connectionId)
{
   OsStatus returnCode = OS_NOT_FOUND;
   CpPhoneMediaConnection* mediaConnection =
       getMediaConnection(connectionId);

   returnCode = doDeleteConnection(mediaConnection);
   return(returnCode);
}
void  CpPhoneMediaInterface::setContactType(int connectionId, CONTACT_TYPE eType) 
{
    CpPhoneMediaConnection* pMediaConn = getMediaConnection(connectionId);

    if (pMediaConn)
    {
        pMediaConn->meContactType = eType ;
    }
}
void ConferenceEngineMediaInterface::removeToneListener(int connectionId)
{
   mLock.acquire();

    ConferenceEngineMediaConnection* pMediaConnection = getMediaConnection(connectionId) ;
    if (pMediaConnection)
    {
        pMediaConnection->mpDTMFNotify = NULL;
    }

    mLock.release();
}
void ConferenceEngineMediaInterface::addToneListener(OsNotification *pListener, int connectionId)
{
    mLock.acquire();

    ConferenceEngineMediaConnection* pMediaConnection = getMediaConnection(connectionId) ;
    if (pMediaConnection)
    {
        pMediaConnection->mpDTMFNotify = pListener;
    }

    mLock.release();
}
OsStatus CpPhoneMediaInterface::startRtpReceive(int connectionId,
                                                int numCodecs,
                                                SdpCodec* receiveCodecs[],
                                                SdpSrtpParameters& srtpParms)
{
   OsStatus returnCode = OS_NOT_FOUND;

   CpPhoneMediaConnection* mediaConnection = getMediaConnection(connectionId);

   if(mpFlowGraph && mediaConnection)
   {
#ifdef TEST_PRINT
      int i;

      OsSysLog::add(FAC_CP, PRI_DEBUG, "Start Receiving RTP/RTCP, %d codec%s; sockets: %p/%p descriptors: %d/%d\n",
           numCodecs, ((1==numCodecs)?"":"s"),
           (mediaConnection->mpRtpSocket),
           (mediaConnection->mpRtcpSocket),
           mediaConnection->mpRtpSocket->getSocketDescriptor(),
           mediaConnection->mpRtcpSocket->getSocketDescriptor());
      for (i=0; i<numCodecs; i++) {
          osPrintf("   %d:  i:%d .. x:%d\n", i+1,
                   receiveCodecs[i]->getCodecType(),
                   receiveCodecs[i]->getCodecPayloadFormat());
      }
#endif

      // Make sure we use the same payload types as the remote
      // side.  It's the friendly thing to do.
      if(mediaConnection->mpCodecFactory)
      {
          mediaConnection->mpCodecFactory->copyPayloadTypes(numCodecs,
                                                           receiveCodecs);
      }

      if(mediaConnection->mRtpReceiving)
      {
         // This is not supposed to be necessary and may be
         // causing an audible glitch when codecs are changed
         mpFlowGraph->stopReceiveRtp(connectionId);
      }

      mpFlowGraph->startReceiveRtp(receiveCodecs, numCodecs,
           *(mediaConnection->mpRtpSocket), *(mediaConnection->mpRtcpSocket),
           connectionId);
      mediaConnection->mRtpReceiving = TRUE;



      returnCode = OS_SUCCESS;
   }
   return(returnCode);
}
void  ConferenceEngineMediaInterface::setContactType(int connectionId, ContactType eType)
{
    mLock.acquire();

    ConferenceEngineMediaConnection* pMediaConnection = getMediaConnection(connectionId) ;
    if (pMediaConnection)
    {
        pMediaConnection->meContactType = eType;
    }

    mLock.release();
}
/* ============================ INQUIRY =================================== */
UtlBoolean ConferenceEngineMediaInterface::isSendingRtpAudio(int connectionId)
{
    mLock.acquire();
    UtlBoolean bSending = FALSE ;

    ConferenceEngineMediaConnection* pMediaConnection = getMediaConnection(connectionId);
    if (pMediaConnection)
    {
        bSending = pMediaConnection->mRtpSending ;
    }

    mLock.release();
    return bSending ;
}
OsNotification* ConferenceEngineMediaInterface::getPlayNotifier(int connectionId)
{
    mLock.acquire();

    OsNotification* notifier = NULL;

    ConferenceEngineMediaConnection* pMediaConnection = getMediaConnection(connectionId) ;
    if (pMediaConnection)
    {
        notifier =  pMediaConnection->mpPlayNotify;
    }

    mLock.release();
    return notifier;
}
UtlBoolean ConferenceEngineMediaInterface::isDestinationSet(int connectionId)
{
    mLock.acquire();
    UtlBoolean bDestination = FALSE ;

    ConferenceEngineMediaConnection* pMediaConnection = getMediaConnection(connectionId);
    if (pMediaConnection)
    {
        bDestination = pMediaConnection->mDestinationSet ;
    }


    mLock.release();
    return bDestination ;
}
OsStatus CpPhoneMediaInterface::stopRtpReceive(int connectionId)
{
   OsStatus returnCode = OS_NOT_FOUND;
   CpPhoneMediaConnection* mediaConnection =
       getMediaConnection(connectionId);

   if(mpFlowGraph && mediaConnection &&
       mediaConnection->mRtpReceiving)
   {
      mpFlowGraph->stopReceiveRtp(connectionId);
      mediaConnection->mRtpReceiving = FALSE;
      returnCode = OS_SUCCESS;
   }
   return(returnCode);
}
OsStatus CpPhoneMediaInterface::deleteConnection(int connectionId)
{
   OsStatus returnCode = OS_NOT_FOUND;
   CpPhoneMediaConnection* mediaConnection =
       getMediaConnection(connectionId);

   UtlInt matchConnectionId(connectionId);
   mMediaConnections.remove(&matchConnectionId) ;

   returnCode = doDeleteConnection(mediaConnection);

   delete mediaConnection ;

   return(returnCode);
}
int ConferenceEngineMediaInterface::getNumCodecs(int connectionId)
{
    mLock.acquire();

    int iCodecs = 0;
    ConferenceEngineMediaConnection*
        pMediaConn = getMediaConnection(connectionId);

    if (pMediaConn && pMediaConn->mpCodecFactory)
    {
        iCodecs = pMediaConn->mpCodecFactory->getCodecCount();
    }

    mLock.release();
    return iCodecs;
}
UtlBoolean CpPhoneMediaInterface::isReceivingRtpAudio(int connectionId)
{
   UtlBoolean receiving = FALSE;
   CpPhoneMediaConnection* mediaConnection = getMediaConnection(connectionId);

   if(mediaConnection)
   {
      receiving = mediaConnection->mRtpReceiving;
   }
   else
   {
       osPrintf("CpPhoneMediaInterface::isReceivingRtp invalid connectionId: %d\n",
          connectionId);
   }
   return(receiving);
}
UtlBoolean CpPhoneMediaInterface::isDestinationSet(int connectionId)
{
    UtlBoolean isSet = FALSE;
    CpPhoneMediaConnection* mediaConnection = getMediaConnection(connectionId);

    if(mediaConnection)
    {
        isSet = mediaConnection->mDestinationSet;
    }
    else
    {
       osPrintf("CpPhoneMediaInterface::isDestinationSet invalid connectionId: %d\n",
          connectionId);
    }
    return(isSet);
}
OsStatus ConferenceEngineMediaInterface::deleteConnection(int connectionId)
{
    mLock.acquire();
    OsStatus rc = OS_NOT_FOUND ;

    ConferenceEngineMediaConnection* pMediaConnection = getMediaConnection(connectionId) ;
    if (pMediaConnection)
    {
        stopRtpSend(connectionId) ;
        stopRtpReceive(connectionId) ;

        OsProtectEventMgr* eventMgr = OsProtectEventMgr::getEventMgr();
        OsProtectedEvent* rtpSockeRemoveEvent = eventMgr->alloc();
        OsProtectedEvent* rtcpSockeRemoveEvent = eventMgr->alloc();
        OsTime maxEventTime(20, 0);

        ConferenceEngineNetTask* pNetTask = NULL;

        pNetTask = ConferenceEngineNetTask::getConferenceEngineNetTask();

        if (pNetTask)
        {
            pNetTask->removeInputSource(pMediaConnection->mpRtpSocket, rtpSockeRemoveEvent) ;
            pNetTask->removeInputSource(pMediaConnection->mpRtcpSocket, rtcpSockeRemoveEvent) ;
            // Wait until the call sets the number of connections
            rtpSockeRemoveEvent->wait(0, maxEventTime);
            rtcpSockeRemoveEvent->wait(0, maxEventTime);
        }

        mpFactoryImpl->releaseRtpPort(pMediaConnection->mRtcpReceivePort) ;

        UtlInt container(connectionId);
        mMediaConnections.destroy(&container);

        int iRC = mpConferenceEngine->GIPSConf_DeleteChannel(connectionId) ;
        assert(iRC == 0);

        eventMgr->release(rtpSockeRemoveEvent);
        eventMgr->release(rtcpSockeRemoveEvent);
        delete pMediaConnection;

        rc = OS_SUCCESS;
    }

    mLock.release();
    return rc ;
}
OsStatus CpPhoneMediaInterface::getCapabilities(int connectionId,
                                                UtlString& rtpHostAddress,
                                                int& rtpAudioPort,
                                                int& rtcpAudioPort,
                                                int& rtpVideoPort,
                                                int& rtcpVideoPort,
                                                SdpCodecFactory& supportedCodecs,
                                                SdpSrtpParameters& srtpParams)
{
    OsStatus returnCode = OS_INVALID;
    rtpHostAddress.remove(0);
    CpPhoneMediaConnection* pMediaConn = getMediaConnection(connectionId);

    if (pMediaConn)
    {
        bool bSet = FALSE ;

        if ((pMediaConn->meContactType == AUTO) || (pMediaConn->meContactType == NAT_MAPPED))
        {
            if (    pMediaConn->mpRtpSocket->getExternalIp(&rtpHostAddress, &rtpAudioPort) && 
                    pMediaConn->mpRtcpSocket->getExternalIp(NULL, &rtcpAudioPort))
            {
                bSet = TRUE ;
            }
        }

        if (!bSet)
        {    
            rtpHostAddress.append(mRtpReceiveHostAddress.data());
            rtpAudioPort = pMediaConn->mRtpReceivePort;
            rtcpAudioPort = pMediaConn->mRtcpReceivePort ;
        }

        supportedCodecs = *(pMediaConn->mpCodecFactory);
        returnCode = OS_SUCCESS;
    }

    rtpVideoPort = 0 ;
    rtcpVideoPort = 0 ;
    memset(&srtpParams, 0, sizeof(SdpSrtpParameters));

    return(returnCode);
}
OsStatus ConferenceEngineMediaInterface::setConnectionDestination(int connectionId,
                                                                  const char* remoteRtpHostAddress,
                                                                  int remoteRtpPort,
                                                                  int remoteRtcpPort,
                                                                  int remoteVideoRtpPort,
                                                                  int remoteVideoRtcpPort)
{
    mLock.acquire();

    ConferenceEngineMediaConnection* pMediaConnection = getMediaConnection(connectionId);
    if (pMediaConnection)
    {
        pMediaConnection->mDestinationSet = TRUE;
        pMediaConnection->mRtpSendHostAddress = remoteRtpHostAddress;
        pMediaConnection->mRtpSendHostPort = remoteRtpPort;
        pMediaConnection->mRtcpSendHostPort = remoteRtcpPort;

        pMediaConnection->mpRtpSocket->doConnect(remoteRtpPort, remoteRtpHostAddress, TRUE);

        int rc = 0;
        if (remoteRtcpPort > 0)
        {
            pMediaConnection->mpRtcpSocket->doConnect(remoteRtcpPort, remoteRtpHostAddress, TRUE);
            rc = mpConferenceEngine->GIPSConf_EnableRTCP(connectionId, TRUE) ;
        }
        else
        {
            rc = mpConferenceEngine->GIPSConf_EnableRTCP(connectionId, FALSE) ;
        }

        if (rc != 0)
        {
            Os::Logger::instance().log(FAC_MP, PRI_ERR,
                          "ConferenceEngineMediaInterface::setConnectionDestination GIPSConf_EnableRTCP failed with error = %d.",
                          mpConferenceEngine->GIPSConf_GetLastError());
        }
        assert(rc == 0) ;
    }

    mLock.release();
    return OS_SUCCESS ;
}
OsStatus ConferenceEngineMediaInterface::getCapabilities(int connectionId,
                                                         UtlString& rtpHostAddress,
                                                         int& rtpPort,
                                                         int& rtcpPort,
                                                         int& rtpVideoPort,
                                                         int& rtcpVideoPort,
                                                         SdpCodecFactory& supportedCodecs,
                                                         SdpSrtpParameters& srtpParams)
{
    mLock.acquire();

    ConferenceEngineMediaConnection* pMediaConn = getMediaConnection(connectionId);
    if (pMediaConn)
    {
        bool bSet = FALSE ;

        if ((pMediaConn->meContactType == AUTO) || (pMediaConn->meContactType == NAT_MAPPED))
        {
            if (pMediaConn->mpRtpSocket->getExternalIp(&rtpHostAddress, &rtpPort) &&
                pMediaConn->mpRtcpSocket->getExternalIp(NULL, &rtcpPort))
            {
                bSet = TRUE ;
            }
        }

        if (!bSet)
        {
            rtpHostAddress = mRtpReceiveHostAddress.data();
            rtpPort = pMediaConn->mRtpReceivePort;
            rtcpPort = pMediaConn->mRtcpReceivePort ;
        }

        supportedCodecs = *(pMediaConn->mpCodecFactory);
        supportedCodecs.bindPayloadTypes();
    }

    mLock.release();
    return OS_SUCCESS ;
}
OsStatus ConferenceEngineMediaInterface::setVolume(int connectionId)
{
    mLock.acquire();

    int iRC;

    ConferenceEngineMediaConnection* pMediaConnection = getMediaConnection(connectionId) ;
    if (pMediaConnection)
    {
        iRC = mpConferenceEngine->GIPSConf_SetVolume(connectionId, mDefaultVolume);
        if (iRC != 0)
        {
            Os::Logger::instance().log(FAC_MP, PRI_ERR,
                          "ConferenceEngineMediaInterface::setVolume GIPSConf_SetVolume failed with error = %d.",
                          mpConferenceEngine->GIPSConf_GetLastError());
        }
        assert(iRC == 0);
    }

    mLock.release();
    return OS_SUCCESS;
}
OsStatus ConferenceEngineMediaInterface::unmute(int connectionId)
{
    mLock.acquire();
    
    int iRC;

    ConferenceEngineMediaConnection* pMediaConnection = getMediaConnection(connectionId) ;
    if (pMediaConnection)
    {        
        iRC = mpConferenceEngine->GIPSConf_StartPlayoutToMeeting(connectionId);
        if (iRC != 0)
        {
            OsSysLog::add(FAC_MP, PRI_ERR,
                          "ConferenceEngineMediaInterface::unmute GIPSConf_StartPlayoutToMeeting failed with error = %d.",
                          mpConferenceEngine->GIPSConf_GetLastError());
        }
        assert(iRC == 0);
    }

    mLock.release();
    return OS_SUCCESS;
}
OsStatus ConferenceEngineMediaInterface::startRtpSend(int connectionId,
                                                      int numCodecs,
                                                      SdpCodec* sendCodecs[],
                                                      SdpSrtpParameters& srtpParams)
{
    mLock.acquire();

    OsStatus status = OS_FAILED;
    int i, rc;
    SdpCodec* primaryCodec = NULL;
    GIPS_CodecInst codecInfo;

    ConferenceEngineMediaConnection* pMediaConnection = getMediaConnection(connectionId);
    if (pMediaConnection && !pMediaConnection->mRtpSending)
    {
        rc = mpConferenceEngine->GIPSConf_SetSendPort(connectionId, pMediaConnection->mRtpSendHostPort) ;
        if (rc != 0)
        {
            Os::Logger::instance().log(FAC_MP, PRI_ERR,
                          "ConferenceEngineMediaInterface::startRtpSend GIPSConf_SetSendPort failed with error = %d.",
                          mpConferenceEngine->GIPSConf_GetLastError());
        }
        assert(rc == 0);

        rc = mpConferenceEngine->GIPSConf_SetSendIP(connectionId, (char*) pMediaConnection->mRtpSendHostAddress.data()) ;
        if (rc != 0)
        {
            Os::Logger::instance().log(FAC_MP, PRI_ERR,
                          "ConferenceEngineMediaInterface::startRtpSend GIPSConf_SetSendIP failed with error = %d.",
                          mpConferenceEngine->GIPSConf_GetLastError());
        }
        assert(rc == 0);

        bool bFoundCodec;
        for (i = 0; i < numCodecs; i++)
        {
            primaryCodec = sendCodecs[i];
            pMediaConnection->mpPrimaryCodec = primaryCodec;

            if (primaryCodec && getConferenceEngineCodec(*primaryCodec, codecInfo))
            {
                Os::Logger::instance().log(FAC_MP, PRI_DEBUG,
                              "ConferenceEngineMediaInterface::startRtpSend: using GIPS codec %s for id %d, payload %d",
                              codecInfo.plname, primaryCodec->getCodecType(),
                              primaryCodec->getCodecPayloadFormat());
                pMediaConnection->mRtpPayloadType = primaryCodec->getCodecPayloadFormat();

                // Forcing ConferenceEngine to use our dynamically allocated payload types
                codecInfo.pltype = primaryCodec->getCodecPayloadFormat();

                rc = mpConferenceEngine->GIPSConf_SetSendCodec(connectionId, &codecInfo);
                if (rc != 0)
                {
                    Os::Logger::instance().log(FAC_MP, PRI_DEBUG,
                                  "ConferenceEngineMediaInterface::startRtpSend: GIPSConf_SetSendCodec failed with error %d",
                                   mpConferenceEngine->GIPSConf_GetLastError());
                }
                assert(rc == 0);

                bFoundCodec = true;
            }

            break;
        }

        if (bFoundCodec)
        {
            rc = mpConferenceEngine->GIPSConf_StartSendToParticipant(connectionId) ;
            if (rc != 0)
            {
                Os::Logger::instance().log(FAC_MP, PRI_ERR,
                              "ConferenceEngineMediaInterface::startRtpSend GIPSConf_StartSendToParticipant failed with error = %d.",
                              mpConferenceEngine->GIPSConf_GetLastError());
            }
            assert(rc == 0);

            pMediaConnection->mRtpSending = TRUE ;
            rc = mpConferenceEngine->GIPSConf_StartPlayoutToMeeting(connectionId) ;
            if (rc != 0)
            {
                Os::Logger::instance().log(FAC_MP, PRI_ERR,
                              "ConferenceEngineMediaInterface::startRtpSend GIPSConf_StartPlayoutToMeeting failed with error = %d.",
                              mpConferenceEngine->GIPSConf_GetLastError());
            }
            assert(rc == 0);

            status = OS_SUCCESS;
        }
        else
        {
            Os::Logger::instance().log(FAC_MP, PRI_ERR,
                          "ConferenceEngineMediaInterface::startRtpSend No match codec is found.");
        }
    }

    mLock.release();
    return status;
}
OsStatus CpPhoneMediaInterface::startRtpSend(int connectionId,
                                             int numCodecs,
                                             SdpCodec* sendCodecs[],
                                             SdpSrtpParameters& srtpParms)
{
   // need to set default payload types in get capabilities

   int i;
   SdpCodec* primaryCodec = NULL;
   SdpCodec* dtmfCodec = NULL;
   OsStatus returnCode = OS_NOT_FOUND;
   CpPhoneMediaConnection* mediaConnection = getMediaConnection(connectionId);
/*
   osPrintf("CpPhoneMediaInterface::startRtpSend(%d, %d, { ",
                  connectionId, numCodecs);
*/
   for (i=0; i<numCodecs; i++) {
      if (SdpCodec::SDP_CODEC_TONES == sendCodecs[i]->getValue()) {
         if (NULL == dtmfCodec) {
            dtmfCodec = sendCodecs[i];
         }
      } else if (NULL == primaryCodec) {
         primaryCodec = sendCodecs[i];
      }
/*
      osPrintf("%d%s", sendCodecs[i]->getValue(),
                     ((numCodecs-1)==i) ? " })\n":", ");
*/
   }
   if(mpFlowGraph && mediaConnection)
   {
#ifdef TEST_PRINT
       OsSysLog::add(FAC_CP, PRI_DEBUG, "Start Sending RTP/RTCP codec: %d sockets: %p/%p descriptors: %d/%d\n",
           primaryCodec ? primaryCodec->getCodecType() : -2,
           (mediaConnection->mpRtpSocket), (mediaConnection->mpRtcpSocket),
           mediaConnection->mpRtpSocket->getSocketDescriptor(),
           mediaConnection->mpRtcpSocket->getSocketDescriptor());
#endif

       // Store the primary codec for cost calculations later
       if (mediaConnection->mpPrimaryCodec != NULL)
       {
           delete mediaConnection->mpPrimaryCodec ;
           mediaConnection->mpPrimaryCodec = NULL ;
       }
       if (primaryCodec != NULL)
       {
           mediaConnection->mpPrimaryCodec = new SdpCodec();
           *mediaConnection->mpPrimaryCodec = *primaryCodec ;
       }

       // Make sure we use the same payload types as the remote
       // side.  Its the friendly thing to do.
       if(mediaConnection->mpCodecFactory)
       {
           mediaConnection->mpCodecFactory->copyPayloadTypes(numCodecs,
                                                            sendCodecs);
       }

       if(mediaConnection->mRtpSending)
       {
//           osPrintf("stop/restarting RTP send\n");
           mpFlowGraph->stopSendRtp(connectionId);
       }

#ifdef TEST_PRINT
      UtlString dtmfCodecString;
      if(dtmfCodec) dtmfCodec->toString(dtmfCodecString);
      OsSysLog::add(FAC_CP, PRI_DEBUG, "CpPhoneMediaInterface::startRtpSend %s using DTMF codec: %s\n",
         dtmfCodec ? "" : "NOT ",
         dtmfCodecString.data());
#endif

      if (!mediaConnection->mRtpSendHostAddress.isNull() && mediaConnection->mRtpSendHostAddress.compareTo("0.0.0.0"))
      {
         // This is the new interface for parallel codecs
         mpFlowGraph->startSendRtp(*(mediaConnection->mpRtpSocket),
                                   *(mediaConnection->mpRtcpSocket),
                                   connectionId,
                                   primaryCodec,
                                   dtmfCodec,
                                   NULL); // no redundant codecs

         mediaConnection->mRtpSending = TRUE;
      }
      returnCode = OS_SUCCESS;
   }
   return(returnCode);
}
OsStatus ConferenceEngineMediaInterface::startRtpReceive(int connectionId,
                                                         int numCodecs,
                                                         SdpCodec* receiveCodecs[],
                                                         SdpSrtpParameters& srtpParams)
{
    mLock.acquire();

    int rc;
    int i;
    SdpCodec* primaryCodec = NULL;
    GIPS_CodecInst codecInfo;

    ConferenceEngineMediaConnection* pMediaConnection = getMediaConnection(connectionId) ;
    if (pMediaConnection && !pMediaConnection->mRtpReceiving)
    {
        pMediaConnection->mpPrimaryCodec = NULL;
        if (pMediaConnection->mpCodecFactory)
        {
            pMediaConnection->mpCodecFactory->copyPayloadTypes(numCodecs, receiveCodecs);
        }

        for (i = 0; i < numCodecs; i++)
        {
            if (NULL == primaryCodec)
            {
                primaryCodec = receiveCodecs[i];
                if (getConferenceEngineCodec(*primaryCodec, codecInfo))
                {
                    // Stop playout here just in case we had a previous giveFocus call. That
                    // will make the SetRecPayloadType call fail. Playout will be resumed
                    // further down.
                    rc = mpConferenceEngine->GIPSConf_StopPlayoutToMeeting(connectionId);
                    if (rc != 0)
                    {
                        Os::Logger::instance().log(FAC_MP, PRI_ERR,
                                      "ConferenceEngineMediaInterface::startRtpReceive GIPSConf_StopPlayoutToMeeting failed with error = %d.",
                                      mpConferenceEngine->GIPSConf_GetLastError());
                    }
                    assert(rc == 0);

                    if (primaryCodec)
                    {
                        codecInfo.pltype = primaryCodec->getCodecPayloadFormat();
                    }

                    rc = mpConferenceEngine->GIPSConf_SetRecPayloadType(connectionId, &codecInfo) ;
                    if (rc != 0)
                    {
                        Os::Logger::instance().log(FAC_MP, PRI_ERR,
                                      "ConferenceEngineMediaInterface::startRtpReceive GIPSConf_SetRecPayloadType failed with error = %d.",
                                      mpConferenceEngine->GIPSConf_GetLastError());
                    }
                    assert(rc == 0);
                }
            }
        }

        pMediaConnection->mRtpReceiving = TRUE ;
        if (pMediaConnection->mpRtpSocket)
        {
            mpNetTask->addInputSource(pMediaConnection->mpRtpSocket) ;
        }

        if (pMediaConnection->mpRtcpSocket)
        {
            mpNetTask->addInputSource(pMediaConnection->mpRtcpSocket) ;
        }

        rc = mpConferenceEngine->GIPSConf_SetRecPort(connectionId, pMediaConnection->mRtpReceivePort + 10);
        if (rc != 0)
        {
            Os::Logger::instance().log(FAC_MP, PRI_ERR,
                          "ConferenceEngineMediaInterface::startRtpReceive GIPSConf_SetRecPort failed with error = %d.",
                          mpConferenceEngine->GIPSConf_GetLastError());
        }
        assert(rc == 0);

#if 0
        // This call only has meaning using internal transport
        rc = mpConferenceEngine->GIPSConf_StartListenToParticipant(connectionId) ;
        if (rc != 0)
        {
            Os::Logger::instance().log(FAC_MP, PRI_ERR,
                          "ConferenceEngineMediaInterface::startRtpReceive GIPSConf_StartListenToParticipant failed with error = %d.",
                          mpConferenceEngine->GIPSConf_GetLastError());
        }
        assert(rc == 0);

        rc = mpConferenceEngine->GIPSConf_StartPlayoutToMeeting(connectionId) ;
        if (rc != 0)
        {
            Os::Logger::instance().log(FAC_MP, PRI_ERR,
                          "ConferenceEngineMediaInterface::startRtpReceive GIPSConf_StartPlayoutToMeeting failed with error = %d.",
                          mpConferenceEngine->GIPSConf_GetLastError());
        }
        assert(rc == 0) ;
#endif
    }

    mLock.release();
    return OS_SUCCESS ;
}