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 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; } }
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()); } } }
/** * handles the INVITED state. * * @param response the response * @param clientTransaction the client transaction * @throws SipException SIP stack related error */ private void handleCallParticipantInvited(Response response, ClientTransaction clientTransaction) throws ParseException, SipException, InvalidArgumentException { FromHeader fromHeader = (FromHeader) response.getHeader(FromHeader.NAME); String displayName = fromHeader.getAddress().getDisplayName(); int statusCode = response.getStatusCode(); Logger.println( "handleCallParticipantInvited " + cp + " status " + statusCode + " " + response.getReasonPhrase()); Logger.println("handleCallParticipantInvited , displayname " + displayName); CallIdHeader callIdHeader = (CallIdHeader) response.getHeader(CallIdHeader.NAME); if (sipCallId.equals(callIdHeader.getCallId()) && displayName.equals(cp.getDisplayName()) && (statusCode == Response.OK || statusCode == Response.SESSION_PROGRESS) && ((CSeqHeader) response.getHeader(CSeqHeader.NAME)).getMethod().equals(Request.INVITE)) { if (statusCode == Response.SESSION_PROGRESS) { /* * For some calls, we never get an OK. Instead we just get * SESSION_PROGRESS. In order to handle these calls, we treat * SESSION_PROGRESS as OK. If an OK arrives later, we'll * send an ACK. This flag allows us to enable or * disable this workaround for each call. * * The problem with always treating SESSION_PROGRESS as OK * is that in a conference everybody will hear the ringing sound * which the remote call sends until the call is actually answered. * This can be avoided if joinConfirmation is specified. * The other problem is that if we treat SESSION_PROGRESS * as though the call has been answered, then we'll start * playing the treatment before a person really answers to * hear the treatment. */ if (cp.getHandleSessionProgress() == false) { Logger.writeFile("Call " + cp + " Ignoring SESSION_PROGRESS"); return; } Logger.writeFile("Call " + cp + " Treating SESSION_PROGRESS as OK"); } if (response.getRawContent() == null) { Logger.error("Call " + cp + " no SDP in OK Response!"); cancelRequest("SIP error! no SDP in OK Response!"); return; } this.clientTransaction = clientTransaction; if (statusCode == Response.OK) { gotOk = true; Logger.writeFile("Call " + cp + " Got OK, call answered\n" + response); } ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME); /* * We got an OK response. * * send an ACK back to the CallParticipant */ if (statusCode == Response.OK) { sipUtil.sendAck(clientTransaction); ackSent = true; } if (callAnswered) { Logger.writeFile("Call " + cp + " done processing OK"); return; } /* * Remember the IP and port of where to send data to * the CallParticipant. */ sdpBody = new String(response.getRawContent()); SdpInfo sdpInfo; try { sdpInfo = sipUtil.getSdpInfo(sdpBody, false); } catch (ParseException e) { Logger.error("Call " + cp + " Invalid SDP in OK Response! " + e.getMessage()); cancelRequest("SIP error! Invalid SDP in OK Response!"); 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); /* * The CallParticipant has answered. * If join confirmation is required, we remain in the * INVITED state. We set the callAnswered flag so that * if the join confirmation times out we know to * send a BYE rather than a CANCEL. */ callAnswered = true; if (cp.getJoinConfirmationTimeout() == 0) { setState(CallState.ANSWERED); } /* * Start treatment if any and wait for it to finish. * When the treatment finishes, notification will * be delivered to our parent which will indicate * we're ready for the conference. * * If there's no treatment to be played, we're ready now * unless we're waiting for join confirmation.. */ initializeCallAnsweredTreatment(); if (callAnsweredTreatment != null) { startCallAnsweredTreatment(); } else { if (cp.getJoinConfirmationTimeout() == 0) { setState(CallState.ESTABLISHED); } } } else { Logger.writeFile("Call " + cp + " Ignoring response: " + response.getReasonPhrase()); if (Logger.logLevel >= Logger.LOG_SIP) { Logger.println("Call " + cp + " Response: " + response); } } }