Example #1
0
  /**
   * Find a call by callId.
   *
   * <p>Calls are kept in the activeCalls list and uniquely identified by
   * <callId>::<name>@<phoneNumber> for a phone call and
   *
   * <p>This method searches for a call with the callId.
   */
  public static CallHandler findCall(String callId) {
    if (Logger.logLevel >= Logger.LOG_DETAIL) {
      Logger.println(
          "findCall:  looking for " + callId + ", " + activeCalls.size() + " active calls");
    }

    synchronized (activeCalls) {
      for (int i = 0; i < activeCalls.size(); i++) {
        CallHandler call = (CallHandler) activeCalls.elementAt(i);

        CallParticipant cp = call.getCallParticipant();

        if (Logger.logLevel >= Logger.LOG_DETAIL) {
          Logger.println("findCall:  looking for " + callId + " got " + cp.getCallId());
        }

        if (match(cp, callId)) {
          if (Logger.logLevel >= Logger.LOG_DETAIL) {
            Logger.println("findCall:  found " + callId);
          }

          return call;
        }
      }
    }
    return null;
  }
Example #2
0
  /** Send indication when a dtmf key is pressed */
  public void dtmfKeys(String dtmfKeys) {
    // if (Logger.logLevel >= Logger.LOG_MOREINFO) {
    Logger.println(cp + " got dtmf keys " + dtmfKeys + " " + cp.dtmfDetection());
    // }

    if (isCallEstablished()) {
      if (cp.dtmfDetection()) {
        member.stopTreatment(null);

        CallEvent callEvent = new CallEvent(CallEvent.DTMF_KEY);
        callEvent.setDtmfKey(dtmfKeys);
        sendCallEventNotification(callEvent);
      }

      if (otherCall != null) {
        Logger.println("Call " + cp + " forwarding dtmf key " + dtmfKeys + " to " + otherCall);
        otherCall.getMemberSender().setDtmfKeyToSend(dtmfKeys);
      } else {
        getMemberSender().setDtmfKeyToSend(dtmfKeys);
      }
    } else {
      if (Logger.logLevel >= Logger.LOG_MOREINFO) {
        Logger.println(cp + " Call not established, ignoring dtmf");
      }
      stopCallAnsweredTreatment();
    }
  }
Example #3
0
  public String noDataReceived() {
    /*
     * Create a packet of silence (linear 0)
     * The dtmf detector needs to know when a dtmf key
     * is released.  If a phone stops sending immediately
     * after the dtmf key is released, we need to append
     * silence so that the dtmf detector will return
     * the dtmf key.
     */
    int[] silence = new int[mediaInfo.getSamplesPerPacket()];

    String dtmfKeys = null;

    dtmfKeys = processData(silence);

    if (Logger.logLevel >= Logger.LOG_DETAIL) {
      Logger.println("no data received, done processing dtmf with silence");

      if (dtmfKeys != null) {
        Logger.println("silence.  dtmf " + dtmfKeys);
      }
    }

    return dtmfKeys;
  }
  private void startSpeaker(AudioFormat format) throws LineUnavailableException {

    speaker.open(format, bufferSize);

    int actualBufferSize = speaker.getBufferSize();

    if (bufferSize != actualBufferSize) {
      Logger.println(
          "Speaker set buffer to " + bufferSize + " but actual size is " + actualBufferSize);

      bufferSize = actualBufferSize;
    }

    if (Logger.logLevel >= Logger.LOG_MOREINFO) {
      Logger.println(
          "Speaker using "
              + getBufferSizeMillis(actualBufferSize)
              + " millisecond buffer "
              + actualBufferSize
              + " bytes");
    }

    speaker.start();
    flush();

    // println("speaker started");
  }
Example #5
0
  /** Done with treatments for call end, now terminate the call */
  public void terminateCall() {
    if (receivedBye == false) {
      if (gotOk == false || (getState() == CallState.INVITED && callAnswered == false)) {

        try {
          Logger.writeFile("Call " + cp + ":  sendCancel");
          sipUtil.sendCancel(clientTransaction);
        } catch (Exception e) {
          Logger.println("sendCancel " + e.getMessage());
        }
      } else {
        /*
         * Try sending a BYE as well.
         * Seems that when we treat SESSION_PROGRESS
         * as OK, sometimes we need to send a CANCEL
         * and other times a BYE.  We'll send both.
         */
        try {
          Logger.writeFile("Call " + cp + ":  sendBye");
          sipUtil.sendBye(clientTransaction);
        } catch (Exception e) {
          Logger.println("Call " + cp + ":  sendBye" + e.getMessage());
        }
      }
    }
  }
Example #6
0
  /*
   * Remove call from list of active calls
   */
  public void removeCall(CallHandler callHandler) {
    synchronized (activeCalls) {
      activeCalls.remove(callHandler); // remove call from list

      Logger.println("");
      Logger.println("calls still in progress:  " + activeCalls.size());
      Logger.println("");
    }
  }
  public static void main(String[] args) {
    if (args.length != 1) {
      Logger.println("Usage:  java Speaker <input file>");
      System.exit(1);
    }

    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

    Speaker speaker = null;

    while (true) {
      try {
        speaker =
            new SpeakerJavasoundImpl(
                8000, 1, RtpPacket.getDataSize(RtpPacket.PCM_ENCODING, 8000, 1));
      } catch (Exception e) {
        Logger.println(e.getMessage());
        System.exit(1);
      }

      Logger.logLevel = 5;

      try {
        TreatmentManager t =
            new TreatmentManager(args[0], 0, speaker.getSampleRate(), speaker.getChannels());

        while (true) {
          byte[] audioData = t.getLinearDataBytes(RtpPacket.PACKET_PERIOD);

          if (audioData == null) {
            break; // end of file
          }

          speaker.write(audioData, 0, audioData.length);
        }
      } catch (IOException e) {
        Logger.println(e.getMessage());
      }

      if (speaker != null) {
        speaker.done();
      }

      Logger.println("Press return to play the file again...");

      try {
        String line = br.readLine();
        if (line.equalsIgnoreCase("quit")) {
          break;
        }
      } catch (IOException ioe) {
        break;
      }
    }
  }
  public void printStatistics() {
    Logger.println(getName() + " " + packetsSent + " packets sent");

    if (packetsSent > 0) {
      Logger.println(
          getName()
              + " average time to send a packet to every member "
              + (totalSendTime / 1000000000. / packetsSent)
              + " seconds ");
    }

    ticker.printStatistics();
  }
Example #9
0
  /*
   * Begin Third-Party Call Control.
   */
  public void initiateCall() throws IOException {
    try {
      try {
        busyTreatment = new TreatmentManager("busy.au", 0);
      } catch (IOException e) {
        Logger.println("Invalid busy treatment:  " + e.getMessage());
      }

      Logger.writeFile("Call " + cp + ":   Begin SIP third party call");

      setState(CallState.INVITED);

      InetSocketAddress isa = callHandler.getReceiveAddress();

      if (isa == null) {
        throw new IOException("can't get receiver socket!");
      }

      // send INVITE to the CallParticipant
      clientTransaction = sipUtil.sendInvite(cp, isa);

      if (clientTransaction == null) {
        Logger.error("Error placing call:  " + cp);
        setState(CallState.ENDED, "Reason='Error placing call'");
        throw new IOException("Error placing call:  " + cp);
      }

      CallIdHeader callIdHeader =
          (CallIdHeader) clientTransaction.getRequest().getHeader(CallIdHeader.NAME);

      sipCallId = callIdHeader.getCallId();

      sipServerCallback = SipServer.getSipServerCallback();
      sipServerCallback.addSipListener(sipCallId, this);
    } catch (java.text.ParseException e) {
      Logger.println("Call " + cp + " Error placing call " + cp + ":  " + e.getMessage());
      setState(CallState.ENDED, "Reason='Error placing call " + cp + " " + e.getMessage() + "'");
      throw new IOException("Error placing call " + cp + " " + e.getMessage());
    } catch (InvalidArgumentException e) {
      Logger.println("Call " + cp + " Error placing call " + cp + ":  " + e.getMessage());
      setState(CallState.ENDED, "Reason='Error placing call " + cp + " " + e.getMessage() + "'");
      throw new IOException("Error placing call " + cp + " " + e.getMessage());
    } catch (SipException e) {
      Logger.println("Call " + cp + " Error placing call " + cp + ":  " + e.getMessage());
      setState(CallState.ENDED, "Reason='Error placing call " + cp + " " + e.getMessage() + "'");
      throw new IOException("Error placing call " + cp + " " + e.getMessage());
    }
  }
Example #10
0
  public DtmfDecoder(MemberReceiver memberReceiver, MediaInfo mediaInfo) {
    this.memberReceiver = memberReceiver;
    this.mediaInfo = mediaInfo;

    decoder = new Decoder();

    linearData = new int[mediaInfo.getSamplesPerPacket()];

    decoder.setRate(mediaInfo.getSampleRate());

    if (mediaInfo.getChannels() != 1) {
      /*
       * Must convert multi-channel to 1
       */
      try {
        sampleRateConverter =
            new SampleRateConverter(
                "DtmfDecoder",
                mediaInfo.getSampleRate(),
                mediaInfo.getChannels(),
                mediaInfo.getSampleRate(),
                1);
      } catch (IOException e) {
        Logger.println("Call " + memberReceiver + " DtmfDecoder:  " + e.getMessage());
      }
    }
  }
    public void run() {
      while (!done) {
        try {
          ConferenceMember member = (ConferenceMember) workToDo.remove();

          try {
            member.sendData();
          } catch (Exception e) {
            e.printStackTrace();

            Logger.println("Can't send data to " + member + " " + e.getMessage());

            member.getCallHandler().cancelRequest("Unexpected Exception");
          }
        } catch (NoSuchElementException e) {
          synchronized (this) {
            doneSignal.countDown();

            if (done) {
              break; // done
            }

            try {
              wait();
            } catch (InterruptedException ie) {
              break;
            }
          }
        }
      }
    }
  public synchronized void done() {
    if (done) {
      return;
    }

    done = true;

    /*
     * There seems to be a bug in the Sun Ray audio system
     * where close() hangs sometimes if there is still data
     * in the speaker buffer.  By sleeping for the time
     * it would take to empty a full buffer (plus some slop),
     * the close() seems to always complete.
     *
     * XXX
     */
    try {
      Thread.sleep(getBufferSizeMillis() + RtpPacket.PACKET_PERIOD);
    } catch (InterruptedException e) {
    }

    synchronized (speaker) {
      speaker.flush();
      speaker.stop();
      speaker.close();
    }

    if (Logger.logLevel >= Logger.LOG_MOREINFO) {
      Logger.println("Speaker closed");
    }
  }
Example #13
0
  /** Mute or unmute the main conference from a particular call. */
  public static void setConferenceSilenced(String callId, boolean isSilenced) {
    synchronized (activeCalls) {
      for (int i = 0; i < activeCalls.size(); i++) {
        CallHandler call = (CallHandler) activeCalls.elementAt(i);

        CallParticipant cp = call.getCallParticipant();

        if (match(cp, callId)) {
          if (Logger.logLevel >= Logger.LOG_DETAIL) {
            String s = "";

            if (isSilenced == false) {
              s = "un";
            }

            Logger.println(cp.getCallId() + ":  silenceMainonference " + s + "muted");
          }

          ConferenceMember member = call.getMember();

          if (member != null) {
            member.setConferenceSilenced(isSilenced);
          }
        }
      }
    }
  }
Example #14
0
  /** Mute or unmute member in a whisperGroup */
  public static void setMuteWhisperGroup(String callId, boolean isMuted) {
    if (callId == null) {
      return;
    }

    synchronized (activeCalls) {
      for (int i = 0; i < activeCalls.size(); i++) {
        CallHandler call = (CallHandler) activeCalls.elementAt(i);

        CallParticipant cp = call.getCallParticipant();

        if (match(cp, callId)) {
          if (Logger.logLevel >= Logger.LOG_DETAIL) {
            String s = "";

            if (isMuted == false) {
              s = "un";
            }
            Logger.println(cp.getCallId() + ":  " + s + "muted");
          }

          MemberReceiver memberReceiver = call.getMemberReceiver();

          if (memberReceiver != null) {
            memberReceiver.setMuteWhisperGroup(isMuted);
          }
        }
      }
    }
  }
  public void setVolumeLevel(double volumeLevel) {
    this.volumeLevel = volumeLevel;

    if (Logger.logLevel >= Logger.LOG_MOREINFO) {
      Logger.println("Setting Speaker volume to " + volumeLevel);
    }

    Utils.setPreference(VOLUME_LEVEL, String.valueOf(volumeLevel));
  }
Example #16
0
  private void handleReInvite(Request request, ServerTransaction st) {
    Logger.println("Call " + cp + " Re-INVITE\n" + request);

    if (request.getRawContent() == null) {
      Logger.error("Call " + cp + " no SDP in INVITE Request!");
      return;
    }

    String sdpBody = new String(request.getRawContent());

    SdpInfo sdpInfo;

    try {
      sdpInfo = sipUtil.getSdpInfo(sdpBody);
    } catch (ParseException e) {
      Logger.error("Call " + cp + " invalid SDP in re-INVITE Request! " + e.getMessage());
      return;
    }

    MediaInfo mediaInfo = sdpInfo.getMediaInfo();

    InetSocketAddress isa = new InetSocketAddress(sdpInfo.getRemoteHost(), sdpInfo.getRemotePort());

    InetSocketAddress rtcpAddress = sdpInfo.getRtcpAddress();

    setEndpointAddress(
        isa,
        mediaInfo.getPayload(),
        sdpInfo.getTransmitMediaInfo().getPayload(),
        sdpInfo.getTelephoneEventPayload(),
        rtcpAddress);

    isa = callHandler.getReceiveAddress();

    try {
      sipUtil.sendOkWithSdp(request, st, isa, sdpInfo);
    } catch (Exception e) {
      Logger.println("Call " + cp + " Failed to send ok with sdp for re-invite " + e.getMessage());
      return;
    }
  }
  private boolean setupSpeaker(String device) throws LineUnavailableException {

    Mixer.Info[] aInfos = AudioSystem.getMixerInfo();

    for (int i = 0; i < aInfos.length; i++) {
      Mixer.Info mixerInfo = aInfos[i];

      if (GetDataLines.equals(device, mixerInfo) == false) {
        if (Logger.logLevel >= Logger.LOG_MOREINFO) {
          Logger.println("Skipping:  " + mixerInfo.getName() + "," + mixerInfo.getDescription());
        }

        continue;
      }

      try {
        Mixer mixer = AudioSystem.getMixer(mixerInfo);

        Line.Info[] infos = mixer.getSourceLineInfo();

        for (int j = 0; j < infos.length; j++) {
          Line line = (Line) mixer.getLine(infos[j]);

          if (line instanceof SourceDataLine) {
            speaker = (SourceDataLine) line;

            if (Logger.logLevel >= Logger.LOG_INFO) {
              Logger.println("Found speaker:  " + j);
            }
            break;
          }
        }
      } catch (Exception e) {
        if (Logger.logLevel >= Logger.LOG_MOREINFO) {
          Logger.println("Exception:  " + e.getMessage());
        }
      }
    }

    return speaker != null;
  }
Example #18
0
  /*
   * terminate a call.
   */
  public void cancelRequest(String reason) {
    if (done) {
      return;
    }

    done = true;

    Logger.println(cp + " Cancel request " + reason);

    if (csa != null) {
      csa.cancelRequest(reason);
    }
  }
Example #19
0
  /*
   * data starts at RtpPacket.HEADER_SIZE
   */
  public String processData(int[] linearData) {
    numberOfTimesCalled++;
    long start = System.currentTimeMillis();

    if (sampleRateConverter != null) {
      try {
        int nSamples = linearData.length;

        linearData = sampleRateConverter.resample(linearData);

        if (Logger.logLevel >= Logger.LOG_DETAIL) {
          Logger.println(
              "Resample for Dtmf:  nSamples " + nSamples + " new nSamples " + linearData.length);
        }
      } catch (IOException e) {
        Logger.println("Call " + memberReceiver + " DtmfDecoder:  " + e.getMessage());
      }
    }

    int keys[] = new int[MAX_KEYS]; // decoded key

    int nkeys = decoder.decode(keys, AudioConversion.intsToShorts(linearData), 0);

    String dtmfKeys = null;

    if (nkeys > 0) {
      char[] charKeys = new char[nkeys];

      for (int i = 0; i < nkeys; i++) {
        charKeys[i] = char_keys[keys[i]];
      }
      dtmfKeys = new String(charKeys);
    }

    totalDecodeTime += (System.currentTimeMillis() - start);

    return dtmfKeys;
  }
  private void singleThreadSendDataToMembers(ArrayList memberList) {
    for (int i = 0; i < memberList.size(); i++) {
      ConferenceMember member = (ConferenceMember) memberList.get(i);

      if (!member.getMemberSender().memberIsReadyForSenderData()) {
        continue;
      }

      long start = 0;

      if (Logger.logLevel == -33) {
        start = System.nanoTime();
      }

      try {
        member.sendData();
      } catch (Exception e) {
        e.printStackTrace();

        Logger.println("Can't send data to " + member + " " + e.getMessage());

        member.getCallHandler().cancelRequest("Unexpected Exception");
      }

      if (Logger.logLevel == -33) {
        Logger.println(
            "Sender sendDataToOneMember time "
                + member
                + " "
                + ((System.nanoTime() - start) / 1000000000.)
                + " seconds");

        Logger.logLevel = 3;
      }
    }
  }
  public synchronized int write(byte[] buffer, int offset, int length) {
    if (speaker == null) {
      return 0;
    }

    start();

    /*
     * Break the buffer up into 20 ms chunks, write as much as we can,
     * then wait until there's room for more.
     */
    int len = length;

    int sleepCount = 0;
    long start = System.currentTimeMillis();

    while (len > 0) {
      int writeLength = Math.min(len, chunkSize);

      while (!done && available() < chunkSize) {
        try {
          Thread.sleep(RtpPacket.PACKET_PERIOD);
          sleepCount++;
        } catch (InterruptedException e) {
        }
      }

      applyVolume(buffer, offset, writeLength);

      speaker.write(buffer, offset, writeLength);

      offset += writeLength;
      len -= writeLength;
    }

    if (sleepCount > 0) {
      if (Logger.logLevel >= Logger.LOG_MOREINFO) {
        long elapsed = System.currentTimeMillis() - start;

        Logger.println("write to speaker slept " + sleepCount + " times, " + elapsed + "ms");
      }
    }

    numWrites++;
    return length;
  }
Example #22
0
  /** Find the new call of a call migration. */
  public static CallHandler findMigratingCall(String callId) {
    synchronized (activeCalls) {
      for (int i = 0; i < activeCalls.size(); i++) {
        CallHandler call = (CallHandler) activeCalls.elementAt(i);

        CallParticipant cp = call.getCallParticipant();

        if (match(cp, callId) && cp.migrateCall()) {
          if (Logger.logLevel >= Logger.LOG_DETAIL) {
            Logger.println("findMigratingCall:  found " + callId);
          }

          return call;
        }
      }
    }
    return null;
  }
Example #23
0
  public static void setDoNotRecord(String callId, boolean doNotRecord)
      throws NoSuchElementException {

    CallHandler callHandler = findCall(callId);

    if (callHandler == null) {
      throw new NoSuchElementException("Invalid callId specified:  " + callId);
    }

    if (Logger.logLevel >= Logger.LOG_DETAIL) {
      String s = "";

      if (doNotRecord == true) {
        s = "NOT";
      }
      Logger.println(callHandler + ":  " + s + " okay to record");
    }

    callHandler.getMemberReceiver().setDoNotRecord(doNotRecord);
  }
Example #24
0
  /**
   * Processes SIP requests. The only request being handled is BYE.
   *
   * @param requestReceivedEvent the event containing the SIP request
   */
  public synchronized void processRequest(RequestEvent requestReceivedEvent) {

    // obtain request and transaction id
    Request request = requestReceivedEvent.getRequest();

    ServerTransaction st = requestReceivedEvent.getServerTransaction();

    if (request.getMethod().equals(Request.BYE)) {
      handleBye(request, st);
    } else if (request.getMethod().equals(Request.INVITE)) {
      /*
       * This is a re-Invite
       */
      handleReInvite(request, st);
    } else if (request.getMethod().equals(Request.ACK)) {
      Logger.println("Call " + cp + " got ACK");
    } else {
      // no other requests should come in other than BYE, INVITE or ACK
      Logger.writeFile("Call " + cp + " ignoring request " + request.getMethod());
    }
  }
Example #25
0
  public TreatmentManager playTreatmentToCall(
      String treatment, TreatmentDoneListener treatmentDoneListener) throws IOException {

    if (Logger.logLevel >= Logger.LOG_MOREINFO) {
      Logger.println("Playing treatment " + treatment + " to " + cp.getCallId());
    }

    TreatmentManager treatmentManager =
        new TreatmentManager(
            treatment,
            0,
            conferenceManager.getMediaInfo().getSampleRate(),
            conferenceManager.getMediaInfo().getChannels());

    if (treatmentDoneListener != null) {
      treatmentManager.addTreatmentDoneListener(treatmentDoneListener);
    }

    addTreatment(treatmentManager);
    return treatmentManager;
  }
Example #26
0
  /** Set flag to do voice detection while muted */
  public static void setVoiceDetectionWhileMuted(String callId, boolean voiceDetectionWhileMuted) {

    if (callId == null) {
      return;
    }

    synchronized (activeCalls) {
      for (int i = 0; i < activeCalls.size(); i++) {
        CallHandler call = (CallHandler) activeCalls.elementAt(i);

        CallParticipant cp = call.getCallParticipant();

        if (match(cp, callId)) {
          cp.setVoiceDetectionWhileMuted(voiceDetectionWhileMuted);

          if (Logger.logLevel >= Logger.LOG_DETAIL) {
            Logger.println(
                cp.getCallId() + " voice detection while muted is " + voiceDetectionWhileMuted);
          }
        }
      }
    }
  }
  public SpeakerJavasoundImpl(int sampleRate, int channels, int bufferSize) throws IOException {

    this.sampleRate = sampleRate;
    this.channels = channels;
    this.bufferSize = bufferSize;

    chunkSize = RtpPacket.getDataSize(RtpPacket.PCM_ENCODING, sampleRate, channels);

    try {
      setupSpeaker();
    } catch (LineUnavailableException e) {
      throw new IOException(e.getMessage());
    }

    if (Logger.logLevel >= Logger.LOG_INFO) {
      Logger.println("New speaker " + sampleRate + "/" + channels + " bufferSize " + bufferSize);
    }

    double volumeLevel = Utils.getDoublePreference(VOLUME_LEVEL);

    if (volumeLevel != -1D) {
      this.volumeLevel = volumeLevel;
    }
  }
Example #28
0
 public void processIOException(IOExceptionEvent ioee) {
   if (Logger.logLevel >= Logger.LOG_SIP) {
     Logger.println("processTransactionTerminated called");
   }
 }
Example #29
0
 public void processTransactionTerminated(TransactionTerminatedEvent tte) {
   if (Logger.logLevel >= Logger.LOG_SIP) {
     Logger.println("processTransactionTerminated called");
   }
 }
Example #30
0
 public void processDialogTerminated(DialogTerminatedEvent dte) {
   if (Logger.logLevel >= Logger.LOG_SIP) {
     Logger.println("processDialogTerminated called");
   }
 }